- Title(EN): Django REST Framework Learning Notes (7): the Serialzier class in serialziers module
- Author: dog2
基本信息
- 源码:
rest_framework.response
- 官方文档
- API Guide - Serializers
- API Guide - Serializer fields
- API Guide - Serializer relations
- 本文demo代码Github
DRF常用序列化类主要有
rest_framework.serialziers.Serializer
rest_framework.serialziers.ModelSerializer
rest_framework.serialziers.ListSerializer
本篇介绍rest_framework.serialziers.Serializer
源码分析
根据基类rest_framework.serialziers.BaseSerializer
构造函数
1 | def __init__(self, instance=None, data=empty, **kwargs): |
定义好Serialzier类后,就可以创建Serializer对象了。Serializer的构造方法为
1 | Serializer(instance=None,data=empty,**kwargs) |
- 用于序列化时,将模型类对象传入
instance
参数 - 用于反序列化时,将要被反序列化的数据传入
data
参数 - 除了
instance
和data
参数外,在构造Serializer
对象时,还可以通过context
参数额外添加数据。通过context
参数附加的数据,可以通过Serializer
对象的context
属性获取。1
serializer = AccountSerializer(account, context={'request':request})
用法
序列化器的使用分两个阶段:
在客户端请求时,使用序列化器可以完成对数据的反序列化(就是前段往后端传递数据,反序列化之后保存数据)
在服务器响应时,使用序列化器可以完成对数据的序列化(服务器取出数据,序列化之后往前段发送展示)
序列化
序列化是将数据返回给前台。DRF的序列化使用流程如下:
- 查询出一个用户对象
1 | from models import user |
- 构造序列化器对象
1 | from user.serializers import UserSerializer |
- 获取序列化对象,通过data属性可以获取序列化后的数据
上面查出来的user_ser是一个serializer对象,需要取出具体的数据传给前端,所有要用到 user_ser.data取出具体数据
1 | user_ser = Userserializer(user).data |
- 如果要被序列化的数据是包含多条数据的(也可以说被[ ]嵌套的,
queryset
类型数据,不管是多条还是单条),需要添加many=True
参数
1 | user = models.User.objects.all() |
- 自定义序列化属性
1 | serializers.SerializerMethodField() |
反序列化使用流程
反序列化是将前天传来的数据数据存入数据库。DRF的反序列化使用流程如下:
数据验证
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用
is_valid()
方法进行验证,验证成功返回True
,否则返回False
。验证失败,可以通过序列化对象的
errors
属性获取错误信息,返回字典,包含了字段和字段的错误。验证通过,可以通过序列化器对象的
validated_data
属性获取数据
保存数据
序列化类中必须重写create
方法用于新增,重写update
方法用于修改。视图中使用create
和save
方法。
从源码可知save
方法内部调用的是序列化类中的create
方法,所以新增必须要在序列化类中重写create
方法。
1 |
用法示例
序列化
模型层 models.py
1 | class User(models.Model): |
配置层 settings.py
1 | # 注册rest_framework |
序列化层 api/serializers.py
api
应用下创建serializers.py
文件- 设置需要返回给前台数据样式 那些
model
类有对应的字段,不需要返回的就不用设置了 - 设置方法字段,字段名可以随意,字段值由
get_字段名
提供,来完成一些需要处理在返回的数据,类似于forms
组件
1 | from rest_framework import serializers, exceptions |
视图层 views.py
- 从数据库中将要序列化给前台的
model
对象,或是多个model
对象查询出来
1 | user_obj = models.User.objects.get(pk=pk) |
或者
1 | user_obj_list = models.User.objects.all() |
- 序列化:
对象.data
就是可以返回给前台的序列化数据
1 | return Response({ |
完整代码:
1 | class User(APIView): |
反序列化
反序列层 api/serializers.py
- 设置必填与选填序列化字段,设置校验规则
- 为需要额外校验的字段提供局部钩子函数,如果该字段不入库,且不参与全局钩子校验,可以将值取出校验
pop
- 为有联合关系的字段们提供全局钩子函数,如果某些字段不入库,可以将值取出校验
- 必须重写
create
方法,完成校验通过的数据入库工作,得到新增的对象
完整代码:
1 | class UserDeserializer(serializers.Serializer): |
视图层 views.py
- 反序列化数据必须赋值
data
,结果就是得到一个serializer
对象
1 | book_ser = serializers.UserDeserializer(data=request_data) |
- 把数据放到自定义
serializer
中校验,数据校验成功返回True
,失败返回False
1 | book_ser.is_valid() |
- 不通过返回
book_ser.errors
给前台,通过book_ser.save()
得到新增的对象,再正常返回
完整代码:
1 | class User(APIView): |
总结
- 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以
- 序列化器无法直接接收数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。(
data
,instance
传参)- 序列化:是数据对象从数据库中查出,通过instance传入序列化器中,必须通过data属性才能将序列化后的数据传给前端,不能直接传序列化对象
- 反序列化:是数据是通过request.data从前端获取到数据,通过data传入序列化器中进行校验,保存到数据库中
- 序列化器的字段声明类似于我们前面使用过的表单系统
- 开发restful api时,序列化器会帮我们把模型数据转换成字典
- drf提供的视图会帮我们把字典转换成json,或者把客户端发过来的数据转换成字典