REST API 已經是目前業界的主流了,網站提供共通的介面,讓其他的應用程式像是手機應用程式、桌面應用程式等來呼叫、操作、使用。Django REST framework 顧名思義,就是為 Django 增加 REST API 功能的框架。在官方網站上的說明是這樣的:「Django REST framework 是強大而且有彈性,可以用來建立 Web API 的工具組。」
不過說到這邊,Django 本身也可以做 API 啊,但是呢,純用 Django 來做,得自己處理 csrf 問題、資料驗證問題、身份驗證問題、權限問題等等的,這些問題都得自己來處理。用 REST framework 的好處是,他把 API 的處理流程,也就是上面提到的這些都歸納為一個 pattern、一個統一的處理流程,只要把該填的、該客製化的部份填上去,一個 API 就完成了。
poetry add djangorestframework
在 settings 裡的 INSTALLED_APPS 加入 rest_framework
INSTALLED_APPS = [
# ...
'rest_framework',
]
另外也可以依照需要加入設定
REST_FRAMEWORK = {
"PAGE_SIZE": 100,
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
}
上面的設定,就是
說真的,REST framework 可以講的東西太多了,這裡我打算花兩個篇幅來講,這篇講跟 Model 結合的部分,下一篇講不使用 Model 的情況以及一些小技巧。
這裡我們要建立一組 API ,這組 API 可以用來取得文章清單名單、新增文章、修改文章跟刪除文章。
首先,先新增一個 app
poetry run python manage.py startapp news
在 settings 的 INSTALLED_APP 加入 "news"
INSTALLED_APPS = [
# 其他,省略
'news',
]
然後定義 model
from django.db import models
# news/models.py
class Reporter(models.Model):
name = models.CharField(max_length=250)
class Article(models.Model):
title = models.CharField(max_length=250)
content = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
建立 migrations,跟 migrate
poetry run python manage.py makemigrations
poetry run python manage.py migrate
接著,要定義 Serializer
# news/serializers.py
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'title', 'content', 'created_at', 'updated_at', 'reporter']
再來是定義 API,這邊因為我們想要提供一整組,包含建立、修改、刪除、查詢等功能,所以可以直接使用 ModelViewSet
# news/viewsets.py
from rest_framework import viewsets
from rest_framework.permissions import AllowAny
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
permission_classes = (AllowAny,)
然後定義 urls
# news/urls.py
from news.viewsets import ArticleViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'articles', ArticleViewSet, basename='article')
urlpatterns = router.urls
最後在專案的 urls 裡把上面的 urlpatterns 加進來。
urlpatterns += [
# API base url
path("api/news/", include("news.urls")),
]
打開瀏覽器,在網址列輸入 http://localhost:8000/api/news/
就可以看到 API 的頁面了。