- 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.Serializerrest_framework.serialziers.ModelSerializerrest_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,或者把客户端发过来的数据转换成字典