Django DRF API

Django 基本使用

前后端分离开发模式

1.1 前后端分离前

Django DRF API_第1张图片

1.2 前后端分离前存在的一些问题

• PC、APP、Pad等多端流行 • 前后端开发职责不清晰:各司其职,最大程度减少开发难度,方便协作 • 开发效率问题,一般后端开发需先等前端页面准备好,有时前端也一直配 合后端,能力受限 • 前后端代码混在一起,日积月累,维护成本增加 • 后端开发语言和模板耦合

1.3 前后端分离开发模式

Django DRF API_第2张图片

RestFulAPI

1.1 什么是RestfulAPI: • REST(Representational State Transfer,表征状态转移)是一种Web服务的软件架构风格。 描述网络中客户端与服务端的一种交互方式,它本身不常用,常用的是如何设计RestfulAPI (REST风格的网络接口) • RestfulAPI风格就是把所有的数据都当做资源,对表的操作就是对资源操作 • 资源就是指的URL,基于URL对资源操作,Web服务在URL上支持一系列请求方法,如下表所 示。

Django DRF API_第3张图片

Django开发模式

1.1 Django工作流程

Django DRF API_第4张图片

1.2 django案列创建一个用户信心管理实现增删改查

1.3.1 首先使用Pycharm创建一个新项目

Django DRF API_第5张图片

1.3.2 创建应用myapp

python manage.py startapp myapp

1.3.3 myapp/models.py编写数据模型

from django.db import models

# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=30)
    city = models.CharField(max_length=30)
    sex = models.CharField(max_length=30)
    age = models.IntegerField()

1.3.4 user_info项目重的settings.py中注册myapp

Django DRF API_第6张图片

1.3.5 user_info 路由urls.py中定义myapp的路由

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/', include('myapp.urls'))
]

1.3.6 同步数据库

python manage.py makemigrations python manage.py migrate

1.3.7 定义应用myapp路由urls.py

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    # path('user/', views.user),
    path('user/', views.UserView.as_view()),
    path('user_add', views.user_add),
    path('user_edit', views.user_edit)
]

1.3.8 定义myapp试图views.py

from django.shortcuts import render
from django.http import HttpResponse, QueryDict, JsonResponse
from .models import User
from django.views.generic import  View

def user_add(request):
    return render(request, 'user_add.html')

def user_edit(request):
    id = request.GET.get('id')
    user_obj = User.objects.get(id=id)
    return render(request, 'user_edit.html', {'id': id, 'user': user_obj})

# def user(request):
#     if request.method == "GET":
#         if request.GET.get('id'):
#             pass
#             # user_obj = User.objects.get(id=request.GET.get('id'))
#             # res = {'code': 200, 'msg': '成功!', user_obj: user_obj}
#             # return JsonResponse(res)
#         else:
#             user_list = User.objects.all()
#             return render(request, 'user_list.html', {'user_list': user_list})
#     elif request.method == "POST":
#         name = request.POST.get('name')
#         city = request.POST.get('city')
#         sex = request.POST.get('sex')
#         age = request.POST.get('age')
#         User.objects.create(
#             name=name,
#             city=city,
#             sex=sex,
#             age=age
#         )
#         return HttpResponse("创建用户成功!")
#     elif request.method == "PUT":
#         data = QueryDict(request.body)
#         id = data.get('id')
#         user_obj = User.objects.get(id=id)
#         user_obj.city = data.get('city')
#         user_obj.sex = data.get('sex')
#         user_obj.age = data.get('age')
#         user_obj.save()
#         # 方式2
#         # data = {'city': data.get('city'), 'sex': data.get('sex'), 'age': data.get('age')}
#         # User.objects.filter(id=id).update(**data)
#         res = {'code': 200, 'msg': '更新成功!'}
#         return JsonResponse(res)
#     elif request.method == "DELETE":
#         data = QueryDict(request.body)
#         id = data.get('id')
#         try:
#             User.objects.get(id=id).delete()
#             res = {'code': 200, 'msg': '删除用户成功!'}
#         except Exception:
#             res = {'code': 500, 'msg': '删除用户失败!'}
#
#         return JsonResponse(res)

class UserView(View):
    def get(self, request):
        if request.GET.get('id'):
            pass
            # user_obj = User.objects.get(id=request.GET.get('id'))
            # res = {'code': 200, 'msg': '成功!', user_obj: user_obj}
            # return JsonResponse(res)
        else:
            user_list = User.objects.all()
            return render(request, 'user_list.html', {'user_list': user_list})

    def post(self, request):
        name = request.POST.get('name')
        city = request.POST.get('city')
        sex = request.POST.get('sex')
        age = request.POST.get('age')
        User.objects.create(
            name=name,
            city=city,
            sex=sex,
            age=age
        )
        return HttpResponse("创建用户成功!")

    def put(self, request):
        data = QueryDict(request.body)
        id = data.get('id')
        user_obj = User.objects.get(id=id)
        user_obj.city = data.get('city')
        user_obj.sex = data.get('sex')
        user_obj.age = data.get('age')
        user_obj.save()
        # 方式2
        # data = {'city': data.get('city'), 'sex': data.get('sex'), 'age': data.get('age')}
        # User.objects.filter(id=id).update(**data)
        res = {'code': 200, 'msg': '更新成功!'}
        return JsonResponse(res)

    def delete(self, request):
        data = QueryDict(request.body)
        id = data.get('id')
        try:
            User.objects.get(id=id).delete()
            res = {'code': 200, 'msg': '删除用户成功!'}
        except Exception:
            res = {'code': 500, 'msg': '删除用户失败!'}

        return JsonResponse(res)

1.3.9 创建添加、编辑、获取用户信息前端html

添加




    
    创建用户


姓名:
城市:
姓名:
年龄:

获取




    
    列出所有用户
    




        {% for i in user_list %}
        
        {% endfor %}
    
ID 姓名 城市 性别 年龄 操作
{{ i.id }} {{ i.name }} {{ i.city }} {{ i.sex }} {{ i.age }}

1.3.10 编辑


    
    编辑用户
    


编辑用户

姓名:
城市:
性别:
年龄:

1.3.11 启动myapp应用

Django REST Framework初探

DRF 实现用户增删改查

1 安装Django REST Framework

pip install djangorestframework

2 添加rest_framework到INSRTALLED_APPS设置中

Django DRF API_第7张图片

3创建app

python manage.py startapp myapp_api

4 定义数据模型并同步数据库

from django.db import models

# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=30)
    city = models.CharField(max_length=30)
    sex = models.CharField(max_length=30)
    age = models.IntegerField()

python manage.py makemigrations python manage.py migrate

5 编写序列化器文件myapp_api/serializers.py

from myapp.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User #指定数据类型
        fields = "__all__" #显示所有字段

6 定义视图

from rest_framework import viewsets
from .serializers import UserSerializer
from myapp.models import User
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all() #指定操作的数据
    serializer_class = UserSerializer #指定序列化器

7 添加API路由devops/urls.py和应用myapp/urls.py

from django.contrib import admin
from django.urls import path ,include,re.path


urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('myapp/',include('myapp.urls')),
    re_path('api/',include('myapp_api.urls')),
]
from django.urls import path,re_path,include
from myapp_api import  views
from rest_framework import routers

#自动注册路由
router = routers.DefaultRouter()
router.register(r'user',views.UserViewSet)

urlpatterns = [
    path('api',include(router.urls))
]

8 调用地址完成增删改查

Django DRF API_第8张图片

Django DRF序列化器

什么是序列化?

序列化 (Serialization),是指把程序中的一个类转化成一个标准化的格式。标准化的意义是这个格式可以跨程序,跨平台的被使用,而且保持其原有的内容,规范。

为什么要对数据进行序列化?

  • 一致性:我们将要保存的数据,序列化成标准的格式(Json格式或者Pickle格式)。之后再反序列化回来,数据依然是原来的。保持了数据的一致性。

  • 有效性: 序列化之后,可以减少内存和网络资源的占用

  • 兼容性: 使用python进行了数据的序列化,也可以使用java或者其他语言进行反序列得到数据进行使用。

什么是序列化?什么是反序列化?

  • 序列化:将python对象转json

  • 反序列化: 将python对象转json

序列化器的工作流程:

序列化(读数据):视图通过ORM从数据库获取数据库查询集对象->数据传入序列化器->

序列化器对数据进行序列化->调用序列化器的.data获取数据->响应返回给前端

反序列化(写数据):试图获取前端提交数据-> 数据传入序列化器->调用序列化器的.is_valid方法效验数据->调用序列化器的.save()方法保存数据

序列化器常用方法与属性:

  • serializer.is_vaild():调用序列化器验证数据,传入raise_exception=True可以在验证失败时由DRF响应400异常

  • serializer.errors: 获取反序列化器验证的错误信息

  • serializer.data:获取序列化器返回的数据

  • serializer.save(): 将验证通过的数据保存到数据库(ORM操作)

DRF中序列化器支持的三种类型:

  • Serializer:对Model(数据模型)进行序列化,但是需要自定义字段映射

  • ModelSerializer:对Model进行序列化,会自动生成字段和验证规则,默认还包含简单的create()和update()方法

  • HyperlinkedModelSerializer: 与ModelSerializer类似,只不过使用超链接来表示关系而不是主键id

DRF序列化器使用

Serializer序列化器

1、获取所有用户(查)

1.1 定义序列化器 myapp_api/serializers.py

class UserSerializer(serializers.Serializer):
    #序列化器中定义的字段必须与使用模型字段对应
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=30)
    city = serializers.CharField(max_length=30)
    sex = serializers.CharField(max_length=30)
    age = serializers.IntegerField()

1.2 视图中使用定义好的序列化器 myapp_api/views.py

from rest_framework.views import APIView
from .serializers import UserSerializer
from myapp.models import User
from rest_framework.response import Response

# class UserViewSet(viewsets.ModelViewSet):
#     queryset = User.objects.all() #指定操作的数据
#     serializer_class = UserSerializer #指定序列化器
class UserView(APIView):
    def get(self,request):
        # 获取所有用户
        queryset = User.objects.all()
        # 调用序列化器将queryset对象转为json
        user_ser = UserSerializer(queryset,many=True) #如果序列化多条数据,需要指定many=True
        return Response(user_ser.data) #从.data属性中获取序列化结果

1.3定义路由myapp_api/urls.py

from django.urls import path,re_path,include
from myapp_api import  views

urlpatterns = [
    path('^api/user/$',views.UserView.as_view()),
]
Django DRF API_第9张图片

2、获取单个用户

2.1 定义获取单个用户视图

from rest_framework.views import APIView
from .serializers import UserSerializer
from myapp.models import User
from rest_framework.response import Response

class UserView(APIView):
    def get(self,request,pk=None):
        if pk:
            # 获取单个用户
            user_obj = User.objects.get(id=pk)
            user_ser = UserSerializer(user_obj)#调用序列化器将获取的单个用户数据对象转换为json
        else:
        # 获取所有用户
            queryset = User.objects.all()
            # 调用序列化器将queryset对象转为json
            user_ser = UserSerializer(queryset,many=True) #如果序列化多条数据,需要指定many=True
        result = {'code':200,'msg': "获取用户成功",'data': user_ser.data}
        return Response(result) #从.data属性中获取序列化结果

2.2 定义路由myapp_api/urls.py

from django.urls import path,re_path,include
from myapp_api import  views
urlpatterns = [
    re_path('^api/user/$',views.UserView.as_view()),
    re_path('^api/user/(?P\d)/$',views.UserView.as_view()),
]

2.3 获取单个用户测试

Django DRF API_第10张图片

3 创建用户

3.1 定义视图myapp_api/views.py 增加post方法接收数据

    def post(self,request):
        #调用序列化器将提交的数据进行反序列化
        user_ser = UserSerializer(data=request.data)
        # 判断提交的数据反序列化是否通过验证
        if user_ser.is_valid():
            # 判断通过则保存到数据库
            user_ser.save()
            msg = '创建用户成功'
            code = 200
        else:
            msg = '提交数据格式不对!创建用户失败'
            code = 400
        result = {'code': code,'msg': msg}
        return Response(result)

3.2 myapp_api/serializers.py定义create()方法

class UserSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=30)
    city = serializers.CharField(max_length=30)
    sex = serializers.CharField(max_length=30)
    age = serializers.IntegerField()

    def create(self, validated_data): # 定义create方法validated_data是提交的json数据
        return User.objects.create(**validated_data)

3.3 测试创建用户

Django DRF API_第11张图片

4、定义更新用户

4.1 定义视图: 增加myapp_api/views.py PUT方法接收数据

    def put(self,request,id=None):
        # 获取需要更新数据的用户,将用户默认pk赋值给id
        user_obj = User.objects.get(id=id)
        # 调用序列化器,传入已有的对象和提交数据
        user_ser = UserSerializer(instance=user_obj,data=request.data)
        if user_ser.is_valid():
            user_ser.save()
            msg = '更新用户成功'
            code = 200
        else:
            msg = '更新用户失败,数据格式不正确!'
            code = 400
        result = {'code': code, 'msg': msg}
        return Response(result)

4.2 myapp_api/serializers.py中增加update()方法

    def update(self, instance, validated_data):
        return User.objects.filter(id=instance.id).update(**validated_data)

4.3 测试更新用户

Django DRF API_第12张图片

5 、删除用户

5.1 定义删除单个用户视图myapp_api/views.py

    def delete(self,request,id=None):
        user_obj = User.objects.get(id=id)
        try:
            user_obj.delete()
            result = {'code': 200, 'msg': '用户删除成功'}
        except Exception as e:
            result = {'code': 500, 'mgs': '用户删除失败'}
        return Response(result)
ModelSerializer 序列化器

ModelSerializer 类型不需要自定义字段映射和定义create、update方法,使用起来方便很多! 如下使用ModelSerializer只需要定义视图、序列化器和自动注册路由

1 定义序列化器 myapp_api/serializers.py

 class UserSerializer(serializers.ModelSerializer): #定义序列化器类,并继承serializers.ModelSerializer
     class Meta:
         model = User #指定数据类型
         fields = '__all__' #显示所有字段

2 定义视图myapp_api/views.py

 class UserViewSet(viewsets.ModelViewSet):
     queryset = User.objects.all() #指定操作的数据
     serializer_class = UserSerializer #指定序列化器

3 定义自动注册路由

from django.urls import path,re_path,include
from myapp_api import  views
from rest_framework import routers

#自动注册路由
router = routers.DefaultRouter()
router.register(r'user',views.UserViewSet)

urlpatterns = [
    path('api',include(router.urls))
]
HyperModelSerializer 序列化器

与MedelSerializer使用方法一样。只不过它使用超链接来表示关系而不是主键ID。


# 更改序列化器
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = "__all__“
# 更改视图
user_ser = UserSerializer(queryset, many=True, context={'request': request})
# 更改路由
re_path('^api/user/$', views.UserView.as_view(), name="user-detail"),
re_path('^api/user/(?P\d+)/$', views.UserView.as_view(), name="user-detail"),
Django DRF API_第13张图片

序列化器常用参数
Django DRF API_第14张图片

1、 在myapp_api/serializers.py中设置序列花器参数

class UserSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True) #当设置为True时该字段提交默认忽略
    name = serializers.CharField(max_length=30,
                                 error_messages={ # 设置错误提示
                                     "blank": "请输入姓名",
                                     "required": "该字段必填",
                                     "max_lenth": "字符长度不超过30",
                                 })
    city = serializers.CharField(max_length=10,
                                 error_messages={  # 设置错误提示
                                     "blank": "请输入城市",
                                     "required": "该字段必填",
                                     "max_lenth": "字符长度不超过10",
                                     })
    sex = serializers.CharField(max_length=10,
                                error_messages={  # 设置错误提示
                                    "blank": "请输入性别",
                                    "required": "该字段必填",
                                    "max_lenth": "字符长度不超10",
                                })
    age = serializers.IntegerField(min_value=18,max_value=100,
                                   error_messages={  # 设置错误提示
                                       "blank": "请输入年龄",
                                       "required": "该字段必填",
                                       "min_value": "年龄不低于18",
                                       "max_value": "年龄不超过100岁",
                                   })

2 、views.py视图修改方法中数据.is_valid(raise_exception=True),下面我只修改了post方法,其他方法修改也是一样的

    def post(self,request):
        #调用序列化器将提交的数据进行反序列化
        user_ser = UserSerializer(data=request.data)
        user_ser.is_valid(raise_exception=True)
        result = {'code': 200,'msg': '创建用户成功'}
        return Response(result)

3、测试post提交数据缺少age字段

Django DRF API_第15张图片
序列器扩展验证规则

当常用参数无法满足验证要求时可以通过钩子方法扩展验证规则

  1. 局部钩子:validate_字段名(self, 字段值)

serializers.py中定义局部钩子

# 局部钩子: 针对某个字段验证合法性
    def validate_name(self,attrs): #attrs是该字段的值
        from re import  findall
        if findall('\d+',attrs):
            raise  serializers.ValidationError("姓名中不能包含数字!")
        else:
            return attrs
Django DRF API_第16张图片

  1. 全局钩子:validate_字段名(self, 字段值)

# 全局钩子:针对所有字段验证
    def validate(self,attrs): #attrs是所有字段组成的字典
        sex = attrs.get('sex')
        if sex != "男" and sex != "女":
            raise serializers.ValidationError("性别只能是男/女!")
        else:
            return attrs
Django DRF API_第17张图片

3 如果钩子也无法满足需求可以,自定义验证器。在序列化类外面定义验证器,使用validators参数指定验证器。

def check_name(data):
    if data.startswith("x"):
        raise serializers.ValidationError("姓名不能以x开头")
    else:
        return data
class UserSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True) #当设置为True时该字段提交默认忽略
    name = serializers.CharField(max_length=30,validators=[check_name],
                                 error_messages={ # 设置错误提示
                                     "blank": "请输入姓名",
                                     "required": "该字段必填",
                                     "max_lenth": "字符长度不超过30",
                                 })
Django DRF API_第18张图片
序列化器关联表显示

如应用发布系统项目涉及表

  • 一对多:一个项目有多个应用,一个应用只能属于一个项目

  • 多对多:一台应用可以部署到多台服务器,一个服务器也能部署多个应用

  1. 创建新应用Association_table

python manager.py startapp Association_table

  1. 定义数据模型,模型定义好了需要同步数据库

python manager.py makemigrations

python manager.py migrate

from django.db import models


class Project(models.Model):
    name = models.CharField(max_length=30)

class App(models.Model):
    name = models.CharField(max_length=30)
    project = models.ForeignKey(Project,on_delete=models.CASCADE) #一对多

class Server(models.Model):
    hostname = models.CharField(max_length=30)
    ip = models.GenericIPAddressField()
    app = models.ManyToManyField(App) #多对多
  1. 定义序列化器

from rest_framework import serializers
from Association_table.models import Project,App,Server

class ProjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Project
        fields = "__all__"

class AppSerializer(serializers.ModelSerializer):
    class Meta:
        model = App
        fields = "__all__"

class ServerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Server
        fields = "__all__"
  1. 定义视图

from  rest_framework.views import APIView
from Association_table.models import Project,App,Server
from .serializers import ProjectSerializer,AppSerializer,ServerSerializer
from rest_framework.response import Response

# Create your views here.
class ProjectView(APIView):
    def get(self, request, id=None):
        if id:
            obj = Project.objects.get(id=id)
            ser = ProjectSerializer(obj)
        else:
            queryset = Project.objects.all()
            ser = ProjectSerializer(queryset, many=True)
        res = {'code': 200, 'msg': '获取成功!', 'data': ser.data}
        return Response(res)
    def post(self, request):
        ser = ProjectSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        res = {'code': 200, 'msg': '创建用户成功!'}
        return Response(res)

class AppView(APIView):
    def get(self, request, id=None):
        if id:
            obj = App.objects.get(id=id)
            ser = AppSerializer(obj)
        else:
            queryset = App.objects.all()
            ser = AppSerializer(queryset, many=True)
        res = {'code': 200, 'msg': '获取成功!', 'data': ser.data}
        return Response(res)
    def post(self, request):
        ser = AppSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        res = {'code': 200, 'msg': '创建用户成功!'}
        return Response(res)

class ServerView(APIView):
    def get(self, request, id=None):
        if id:
            obj = Server.objects.get(id=id)
            ser = ServerSerializer(obj)
        else:
            queryset = Server.objects.all()
            ser = ServerSerializer(queryset, many=True)
        res = {'code': 200, 'msg': '获取成功!', 'data': ser.data}
        return Response(res)
    def post(self, request):
        ser = ServerSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        res = {'code': 200, 'msg': '创建用户成功!'}
        return Response(res)
  1. 定义路由

from django.urls import re_path
from . import  views
urlpatterns = [
    re_path('^api/project/$', views.ProjectView.as_view()),
    re_path('^api/app/$', views.AppView.as_view()),
    re_path('^api/server/$', views.ServerView.as_view()),

]
  1. 添加测试数据

创建项目:
from Association_table.models import Project, App, Server
Project.objects.create(name="电商")
Project.objects.create(name="教育")
创建应用并指定项目:
project_obj = Project.objects.get(name="电商")
App.objects.create(name="portal", project=project_obj)
App.objects.create(name="gateway", project=project_obj)
创建服务器:
Server.objects.create(hostname="test1", ip="192.168.31.10")
Server.objects.create(hostname="test2", ip="192.168.31.11")
将应用部署到服务器:
app_obj = App.objects.get(name="portal")
server_obj = Server.objects.get(hostname="test1")
server_obj.app.add(app_obj)

7 序列化器返回是当前模型中的字段,如果字段是外键时,返回的是外键对应的id,如下图所示

Django DRF API_第19张图片

对于这种情况有两种方法可以显示外键对应的详细信息

  • 定义字段为外键对应序列化类:例如project=ProjectSerializer(read_only=Ture),该方法适合针对某个外键字段。

class AppSerializer(serializers.ModelSerializer):
project = ProjectSerializer(read_only=True) # 一对多,返回关联的项目详情
class Meta:
model = App
fields = "__all__"
  • 序列化类中Meta类启用dpth:深度获取关联表数据,这种对所有外键都会显示

class AppSerializer(serializers.ModelSerializer):
class Meta:
model = App
fields = "__all__"
depth = 1

修改后如下图就可以显示外键对应的详细值

Django DRF API_第20张图片
SerializerMethodField

SerializerMethodField可以在不修改数据模型的前提下,增加API字段

DRF序列器默认返回数据模型中已存在资源,如果想新增返回字段或者二次处理,则需要用用到SerializerMethodFiled

#实例给项目API增加一个字段,这个字段数据可以从别的表中获取
class ProjectSerializer(serializers.ModelSerializer):
    app_acount = serializers.SerializerMethodField()
    class Meta:
        model = Project
        fields = "__all__"
def get_app_acount(self,obj):
    return len(obj.app_set.all())
Django DRF API_第21张图片
序列化和反序列化的行为:
  • to_internal_value():处理反序列化的输入数据,自动转换Python对象,方便处理

  • to_representation():处理序列化数据的输出。

什么时候需要用到反序列化的行为?

当提交API数据与序列化器要求的格式不符合时,序列化就会抛出错误,这个时候就可以使用to_internal_value()方法来提取符合序列化器要求的数据格式

例如:前端提交一个创建新项目的数据

{

"data": {

"id": 3,

"name": "大数据"

},

"extra_data":{

"count": 123

}

}

如下在序列化器中将符合序列化器的data数据使用to_internal_value方法重写后,就可以正常创建了

class ProjectSerializer(serializers.ModelSerializer):
    app_acount = serializers.SerializerMethodField()
    class Meta:
        model = Project
        fields = "__all__"
    def get_app_acount(self,obj):
        return len(obj.app_set.all())

     def to_internal_value(self, data):
         # data是前端提交未验证的数据
         data = data['data']
         return super().to_internal_value(data)

Django DRF API_第22张图片

什么时候用到序列化行为?

当需要给返回的数据添加一个统计应用数量的字段时

class ProjectSerializer(serializers.ModelSerializer):
    #app_acount = serializers.SerializerMethodField()
    class Meta:
        model = Project
        fields = "__all__"

    # def get_app_acount(self,obj):
    #     return len(obj.app_set.all())
    def to_representation(self, instance):
        data = super().to_representation(instance) #获取预返回前的数据
        data['app_acount'] = len(instance.app_set.all())
        return data

你可能感兴趣的:(Python,django,python,后端)