目录
一、序列化器 Serializer
- 序列化:序列化器会把模型对象转换成字典,经过Response以后变成JSON格式字符串
- 反序列化:把客户端发送过来的数据,经过Request以后变成字典,序列化器可以把字典转成模型
- 反序列化:完成数据校验功能
1.1 定义序列化器
Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer类。
为了序列化器能够很好的演示出来,我们需要在一个新的app应用下面开始
python3 manage.py startapp app01
接下来我们还需要定义一个模型类
from django.db import models
class Student(models.Model):
# 模型字段
name = models.CharField(max_length=100,verbose_name="姓名")
sex = models.CharField(max_length=10,verbose_name='性别')
age = models.IntegerField(verbose_name="年龄")
phone = models.CharField(max_length=12,verbose_name='电话号码')
别忘记执行两部迁移操作
python3 manage.py makemigrations
python3 manage.py migrate
保存一些数据
在应用下创建serializer.py文件来存放序列化器
class StudentSerializer(serializers.Serializer):
'''
在视图内获取了模型类里面的值(QuerySet类型)
实现的结果等同于基于QuerySet内容进行for循环这个序列化器,将QuerySet中的每个对象属性值
赋给以下和对象属性名相同的字段作为值
'''
id = serializers.IntegerField() # 接收模型类对象的id属性值
name = serializers.CharField() # 接收模型类对象的name属性值
sex = serializers.CharField()
age = serializers.IntegerField()
phone = serializers.CharField()
其实本质上就相当于key:value的形式接收值
- 视图传递了{“name”:‘jack’}到序列化器内
- 序列化器定义name字段来接收’jack’这个值
如果了解过forms组件的小伙伴就能发现它们之间其实非常相似,反序列化时我们则会了解到字段校验,它还包括有:局部钩子、全局钩子。
注意:serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。
1.2 Serializer对象
Serializer类的构造方法为
Serializer(instance=None, data=empty, **kwarg)
说明:
-
用于序列化时,将模型类对象传入instance参数
-
用于反序列化时,将要被反序列化的数据传入data参数
-
除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如:
serializer = StudentSerializer(name, context={ 'request': request})
通过context参数附加的数据,可以通过Serializer对象的context属性获取。
- 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。
- 序列化器无法直接接收数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。
- 序列化器的字段声明类似于我们前面使用过的表单系统。
- 开发restful api时,序列化器会帮我们把模型数据转换成字典.
- drf提供的视图会帮我们把字典转换成json,或者把客户端发送过来的数据转换字典.
1.3 序列化器的作用
序列化器的使用分两个阶段:
- 在客户端请求时,使用序列化器可以完成对数据的反序列化。
- 在服务器响应时,使用序列化器可以完成对数据的序列化。
二、序列化器的使用
2.1 基本使用
通过将值传递给序列化器完成对值的序列化,DRF内会序列化成JSON格式,然后进行响应
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import serializer
from app01 import models
class BookView(APIView):
def get(self,request):
# 获取所有学生对象保存在QuerySet查询集里面
student_list = models.Student.objects.all()
# 如果传递给序列化器的是一个QuerySet查询集类型的数据,那么则需要增加参数many=True
ser = serializer.StudentSerializer(instance=student_list,many=True)
# 序列化后的数据保存在序列化器对象的data属性内
return Response(ser.data)
然后我们配置路由
from django.urls import path
from app01 import views
urlpatterns = [
path('book/',views.BookView.as_view())
]
已经可以通过浏览器查询到数据了,默认DRF会将数据渲染到它内部的一个API.html模板内,然后响应给浏览器供我们展示
我们在序列化器里面定义的字段决定了能够响应给客户端什么样的数据,如果只定义了id字段,那么就字段接收到QuerySet里对象的id属性,返回给客户端的自然也就只有id字段的数据了
此时我们进行的就是反序列化操作,将客户端传递的数据通过序列化器进行反序列化成为我们可以识别的数据,然后存入数据库。
2.2 处理POST请求数据
当我们对传递进来的数据有一定要求时就要对其进行校验,而序列化器正好可以达到这一目的。那么我们对其稍作改动
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from app01 import models
class StudentSerializer(serializers.Serializer):
# required字段可以不传值(因为在模型类里面它是一个自增的字段)
id = serializers.IntegerField(required=False)
name = serializers.CharField(max_length=10,error_messages={
'max_length':'名称不能超过10位数哦'},required=False)
sex = serializers.CharField(required