DRF快速上手

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

DRF 快速上手

本教程将创建一套简单的 API,可以让管理员查看和编辑系统中的用户和分组。


项目配置

  • 创建项目目录 tutorial
C:\code  
λ mkdir tutorial

C:\code  
λ cd tutorial
复制代码
  • 生成并激活虚拟环境
C:\code\tutorial  
λ python -m venv venv

C:\code\tutorial  
λ cd venv/scripts

C:\code\tutorial\venv\Scripts  
λ activate
复制代码
  • 升级 pip 到最新版(20.2.4
C:\code\tutorial  
(venv) λ python -m pip install -U pip
...
Successfully installed pip-20.2.4
复制代码
  • 安装 Django 以及 DRF
C:\code\tutorial  
(venv) λ pip install django
...
Successfully installed asgiref-3.2.10 django-3.1.2 pytz-2020.1 sqlparse-0.4.1

C:\code\tutorial  
(venv) λ pip install djangorestframework
...
Successfully installed djangorestframework-3.12.1
复制代码
  • 创建项目 tutorial,注意命令后面的 .,表示以当前所在位置为项目根目录,也就是会把 settings.py 放在当前目录。
C:\code\tutorial  
(venv) λ django-admin startproject tutorial .
复制代码
  • tutorial 是一个单应用项目,下面创建应用 quickstart
C:\code\tutorial  
(venv) λ cd tutorial

C:\code\tutorial\tutorial  
(venv) λ django-admin startapp quickstart

C:\code\tutorial\tutorial  
(venv) λ cd ..

C:\code\tutorial  
(venv) λ 
复制代码
  • 最终的项目结构如下

  • 应用 quickstart 被放在 tutorial 项目文件夹中,这看起来有点奇怪,但这样做可以利用项目的命名空间来避免与外部模块产生命名冲突。

注:如果有一个外部模块叫做 quickstart 的话,按照传统的项目结构布局会在导入 quickstart 应用时会产生冲突。但是将应用放在项目设置文件夹中,导入时就需要写出 tutorial.quickstart.xxx 的形式,此时项目文件夹形成了一个包命名空间,减少了命名冲突可能性。

  • 执行迁移,同步数据库
C:\code\tutorial  
(venv) λ python manage.py migrate
复制代码
  • 创建一个超级用户 admin,密码为 123
C:\code\tutorial  
(venv) λ python manage.py createsuperuser --username admin --email admin@example.com
复制代码

序列化器

  • 首先定义一些序列化器,创建新模块 tutorial/quickstart/serializers.py,它将用于呈现数据。
from django.contrib.auth.models import Group, User
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']
复制代码
  • 本例中使用了 HyperlinkedModelSerializer 的超链接关系,你还可以使用主键或者各种其他的关系,但超链接是优秀的 RESTful 设计。

视图

  • 打开 tutorial/quickstart/views.py 编写视图
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsets
from tutorial.quickstart.serializers import GroupSerializer, UserSerializer


class UserViewSet(viewsets.ModelViewSet):
    """
    允许查看和编辑用户的 API 终点。
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]


class GroupViewSet(viewsets.ModelViewSet):
    """
    允许查看和编辑分组的 API 终点。
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
    permission_classes = [permissions.IsAuthenticated]
复制代码
  • 这里将所有常见操作集成到一个叫做视图集 ViewSet 的类中,而不是分开编写多个视图。
  • 如果有需要,也可以将视图集拆解为多个独立视图,但是视图集可以很好地组织视图逻辑,并且非常简洁。

路由

  • 开始编写 APIURL,打开 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)

# 使用自动路由连接 API
# 此外,为可浏览的 API 包含了 login 路由
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
复制代码
  • 因为我们使用了视图集而不是视图,所以可以自动为 API 生成 URL 配置,只需要通过 router 类注册视图集即可。
  • 如果需要进一步控制 APIURL,可以使用普通的类视图,并显式编写路由配置文件。
  • 最后,我们包含了默认的登录和注销视图,以便在可浏览的 APIbrowsable API)中使用。这是可选的,如果 API 需要身份验证且你需要使用可浏览的 API 时,他会变得非常有用。

分页

  • 分页可以控制每一页返回多少个对象。可以在 tutorial/settings.py 中添加如下配置以开启分页功能。
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
}
复制代码

设置

  • tutorial/settings.py 中注册 DRF 应用
INSTALLED_APPS = [
    ...
    'rest_framework',
]
复制代码

测试 API

  • 开启 Django 内置的开发服务器
C:\code\tutorial  
(venv) λ python manage.py runserver
复制代码
  • 通过命令行工具(curl 或者 httpie)访问接口,也可以直接使用浏览器访问 http://127.0.0.1:8000/users/
  • 点击右上角,输入用户名 admin 和密码 123 之后登录,之后就可以管理用户了