快用Django REST framework寫寫API吧

Django默認是前後端綁定的,提供了Template和Form,現在流行前後端分離項目,Python大佬坐不住了,於是便有了Django REST framework://github.com/tomchristie

官網://www.django-rest-framework.org/

Django REST framework(簡稱DRF)是個Python技術棧的後端框架,用來構建RESTful API。

RESTful API

REST,是指REpresentational State Transfer,有個精闢的解釋什麼是RESTful:

  • 看URL就知道要什麼
  • 看Method就知道幹什麼
  • 看Status Code就知道結果如何

良好的RESTful API設計的基本原則是:

  • 返回JSON
  • 嚴禁亂用狀態碼
  • 處理好分頁
  • 返回具體的實體數據而不是返回通用的JSON數據
  • 請求對象有默認值

創建項目

接下來我們使用DRF創建一個簡單的API,允許管理員查看和編輯用戶和組。

先創建名為tutorial的project和名為quickstart的app:

# 創建項目目錄
mkdir tutorial
cd tutorial

# 創建Python虛擬環境
python -m venv env
# 激活虛擬環境
env\Scripts\activate.bat  
# Mac中使用`source env/bin/activate`

# 在虛擬環境中安裝Django和Django REST framework
pip install django
pip install djangorestframework

# 創建project,注意最後有個「.」,表示在當前目錄創建
django-admin startproject tutorial .
cd tutorial
# 創建app
django-admin startapp quickstart
cd ..

創建好的目錄結構如下:

$ pwd
<some path>/tutorial
$ find .
.
./manage.py
./tutorial
./tutorial/__init__.py
./tutorial/quickstart
./tutorial/quickstart/__init__.py
./tutorial/quickstart/admin.py
./tutorial/quickstart/apps.py
./tutorial/quickstart/migrations
./tutorial/quickstart/migrations/__init__.py
./tutorial/quickstart/models.py
./tutorial/quickstart/tests.py
./tutorial/quickstart/views.py
./tutorial/settings.py
./tutorial/urls.py
./tutorial/wsgi.py

一般不會把app放到project裏面,這裡是為了避免命名衝突。

接着同步數據庫:

python manage.py migrate

然後創建一個超級管理員,密碼password123

python manage.py createsuperuser --email [email protected] --username admin

Serializers

序列化是指把數據庫模型轉換為JSON。新建模塊tutorial/quickstart/serializers.py

from django.contrib.auth.models import User, Group
from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'groups']


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ['url', 'name']

Views

視圖用來接受Web請求並且返回Web響應。打開tutorial/quickstart/views.py,添加代碼:

from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework import permissions
from tutorial.quickstart.serializers import UserSerializer, GroupSerializer


class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]


class GroupViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
    permission_classes = [permissions.IsAuthenticated]

URLs

配置路由,打開tutorial/urls.py,添加代碼:

from django.urls import include, path
from rest_framework import routers
from tutorial.quickstart import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

因為這裡用的不是view而是viewsets,所以可以自動生成API的URLconf,只需要註冊class即可。

也可以不用viewsets,用view,再自定義API URL。

Pagination

分頁用來控制每頁返回多少數據,在tutorial/settings.py中添加:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

Settings

tutorial/settings.py中,把'rest_framework'添加到INSTALLED_APPS

INSTALLED_APPS = [
    ...
    'rest_framework',
]

測試API

啟動項目:

python manage.py runserver

訪問//127.0.0.1:8000/users/,點擊右上角用超管登錄,即可看到:

東方說

本文是Django REST framework系列的開篇,內容參考的是官網的Tutorial。學了Django再看DRF,思路清晰多了,雖然我代碼能力不強,但總是在追求規範和標準,難道是因為做測試的職業病么?

終於修復了從博客園複製粘貼到公眾號代碼塊自動換行沒有滾動條的問題,F12看了才知道有個樣式被覆蓋了,加上這句就搞定了:

#topics .postBody pre {
    white-space: pre !important;
}

參考資料:

//www.django-rest-framework.org/tutorial/quickstart/

//www.ruanyifeng.com/blog/2014/05/restful_api.html