目录

了解django-rest-framework

django-rest-framework

Django REST 框架是用于构建 Web API 的强大而灵活的工具包。

您可能想要使用 REST 框架的一些原因:

1.1 安装DRF

1
2
pip3 install djangorestframework
pip3 install pymysql

1.2 添加django-rest-framework

添加完成以后就可以使用DRF提供的功能进行api接口的开发了.

  • 将请求的数据(例如json格式)转化为模型类对象(反序列化)
  • 操作数据库
  • 将模型类对象转换为相应的数据,例如转换为json(序列化)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
INSTALLED_APPS = [
    # 添加你的应用
    'system_manager_api.applications.account',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 添加rest_framework
    'rest_framework'
]

1.3 体验简单的DRF

假设这个地方你已经创建了模型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import json

from django.shortcuts import render
from django.views import View
from system_manager_api.applications.account import models
from django.http import JsonResponse


class AccountView(View):
    """
    POST /accounts/ 添加用户信息
    GET /accounts/  获取用户信息
    GET /accounts/<pk> 获取一个用户信息
    PUT /accounts/<pk> 更新一个用户信息
    DELETE /accounts/<pk> 删除一个用户信息
    """

    def post(self, request):
        """添加一个用户信息"""
        # 接收客户端的数据
        username = request.POST.get('username')
        password = request.POST.get('password')
        mobile_phone = request.POST.get('mobile_phone')
        user_email = request.POST.get('email')
        # 验证客户端数据

        # 更新数据库
        instance = models.User.objects.create(
            username=username,
            password=password,
            mobile_phone=mobile_phone,
            email=user_email
        )
        # 返回结果

        return JsonResponse(data={
            "id": instance.id,
            "name": instance.username,
            "mobile_phone": instance.mobile_phone,
            "email": instance.email
        }, status=201)

    def get(self, request):
        """获取多个用户信息"""

        # 获取数据
        user_list = list(models.User.objects.values())

        return JsonResponse(data=user_list, status=200, safe=False)


class AccountInfoView(View):
    def get(self, request, uid):
        "获取某一条数据"
        try:
            instance = models.User.objects.get(id=uid)
            return JsonResponse(data={
                "username": instance.username,
            }, status=200)
        except models.User.DoesNotExist:
            return JsonResponse(status=404)  # 没有内容

    def put(self, request, uid):
        """更新数据"""
        data = json.loads(request.body)
        print(f'{data}')
        username = data.get('username')
        password = data.get('password')
        mobile_phone = data.get('mobile_phone')
        user_email = data.get('email')
        try:
            instance = models.User.objects.get(id=uid)
            instance.username = username
            instance.password = password
            instance.mobile_phone = mobile_phone
            instance.email = user_email
            instance.save()
            return JsonResponse(data={
                "username": instance.username,
                "password": instance.password,
                "mobile_phone": instance.mobile_phone
            }, status=200)
        except models.User.DoesNotExist:
            return JsonResponse(data={
                "msg": "Not fount"
            }, status=404)  # 没有内容

你可以通过POSTMAN来请求借口

1
{"id": 1, "name": "admin", "mobile_phone": "xxxxxxx", "email": "xxxxx@163.com"}

1.3.1 使用DRF快速生成API接口(生成序列化器)

  • 序列化:把我们是别的数据转换成指定的格式提供给别人.
  • 反序列化:把别人提供的数据转换成我们所需要的格式
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 在你的account目录中新建一个userserializers.py文件
from django.urls import path, include
from system_manager_api.applications.account import models
from rest_framework import routers, serializers, viewsets

# 用户序列化
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User # 提供序列化的模型类
        # 返回所有字段
        fields = '__all__'



# 用户序列化视图设置,当然你也可以单独的写到Views.py中
class UserViewSet(viewsets.ModelViewSet):
    queryset = models.User.objects.all()
    serializer_class = UserSerializer
1
2
3
4
5
6
7
8
9
# account/urls.py
router = DefaultRouter()
# 用户接口
router.register("user", UserViewSet, basename='user'),

urlpatterns = [
    path("account/", views.AccountView.as_view()),
    re_path("account/(?P<uid>\\d)/", views.AccountInfoView.as_view())
] + router.urls
1
2
3
4
5
6
7
8
9
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    # 主路由中需要加入api路径
    path('api/',include("system_manager_api.applications.account.urls"))
]

1.3.2 生成的API接口操作

请求: http://127.0.0.1:8000/api/

1
2
3
4
5
6
7
8
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{	
    # 表示当前你user的用户接口
    "user": "http://127.0.0.1:8000/api/user/"
}

请求: http://127.0.0.1:8000/api/user/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 4,
        "username": "xiaohong",
        "password": "12312312312312",
        "last_login": null,
        "mobile_phone": "xxxxxxxx",
        "email": "xxxxx@163.com",
        "is_superuser": true,
        "is_staff": false,
        "is_activate": true,
        "created_at": "123"
    },
    {
        "id": 1,
        "username": "xiaoming",
        "password": "123123",
        "last_login": null,
        "mobile_phone": "xxx",
        "email": "xxx@qq.com",
        "is_superuser": false,
        "is_staff": false,
        "is_activate": false,
        "created_at": "1650337113.4884014"
    }
]

1.4 序列化器

  • 序列化: 序列化器会把模型对象全部转换为字典,经过response以后变成json字符串
  • 反序列化: 把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转换成模型

1.4.1 定义序列化器

使用Django REST framework中的Serializer类来定义,必须继承来自rest_framework.serializers.Serialize

serializers 是drf提供的给开发者吊用的序列化器模块

Serializer: 序列器化基类,drf所有的序列化器类都必须继承.

ModelSerializer: 模型序列化器类,是序列化器基类的子类,除了Serializer基类中最常用的序列化器类、

1
2
3
4
5
6
7
class TestSerializer(serializers.Serializer):
    # 1. 转换的字段声明
    # 客户端字段 = serializers.字段类型(选项)
    id = serializers.IntegerField()
    username = serializers.CharField()
    mobile_phone = serializers.BooleanField()
    email = serializers.EmailField()

尝试着在django自带的View视图中进行调用

访问:http://127.0.0.1/api/account/

  • api的路径是你自己写在urls.py当中的
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class AccountView(View):
    def get2(self, request):
        """序列化器-序列化阶段的调用-提供数据给客户端"""
        # 首先获取数据集.只获取一个数据
        instance = models.User.objects.first()

        # 1. 实例化序列化器 得到序列化对象
        serializer = TestSerializer(instance=instance)

        # 2. 调用实例化对象的data属性方法得到转换后的数据
        data = serializer.data

        # 3. 响应数据
        return JsonResponse(data=data, status=200, safe=False)

    def get(self, request):
        """序列化器-序列化阶段的调用-提供数据给客户端"""
        # 首先获取数据集,获取多个数据
        user_list = models.User.objects.all()

        # 1. 实例化序列化器,如果是模型对象为多个请务必加入 many=True
        serializer = TestSerializer(instance=user_list, many=True)

        # 2. 调用实例化对象的data属性方法得到转换后的数据
        data = serializer.data

        # 3. 响应数据
        return JsonResponse(data=data, status=200, safe=False)
1
2
3
4
# 如果是一行数据
{"id": 2, "username": "supervis", "mobile_phone": "xxxx", "email": "xxxx@gmail.com", "created_at": "2022-04-20T18:29:42+08:00"}
# 如果是多个数据
[{"id": 2, "username": "supervis", "mobile_phone": "1xxxx", "email": "xxx@gmail.com", "created_at": "2022-04-20T18:29:42+08:00"}, {"id": 1, "username": "admin", "mobile_phone": "xxxx", "email": "xxxx@163.com", "created_at": "2022-04-20T18:03:21+08:00"}]

1.4.2 创建serializer对象

Serializer的构造方法为

1
TestSerializer(instance=instance=None, date=empty, **kwargs)
  • instance: 将模型类对象传入instance参数
  • data: 反序列化的时候,将要被反序列化的数据传入data参数中
  • 除了instancedata参数外,在构造对象的时候,还可以传入context参数添加额外数据
1
serializer = TestSerializer(instance=instance,context={'request':request})
序列化注意事项
  1. 使用序列化器的时候,序列化器声明以后不会自动执行,需要我们在视图中进行调用才可以
  2. 序列化器无法直接接收数据,需要再试图创建序列化器对象的时候,将数据传递进去
  3. 序列化器字段的声明类似于表单系统
  4. 开发restapi的时候,序列化器会帮我们把模型转换成字典
  5. drf提供的试图会帮我们把字典转换成json,或者把客户端发送过来的数据转化为字典