DRF 2 序列化器
2 序列化器
作用:
-
序列化,把模型对象转换成字典
因为def规范要求response需要返回json格式数据,但是查表得到的是一个表模型对象,而python中对象不能被json序列化,所以需要将对象转成字典(手动实现:一个个取对象的属性用for生成字典)再用response处理(内部自动序列后)返回json格式数据
-
反序列化 把字典格式的数据写入表模型中
客户端发送过来的数据,经过request处理后得到一个字典,虽然用**将字典传入可以快速写入数据,但是写入之前先要判断k与字段名知否对应,序列化器则简化了这两个步骤.
2.1 半自动序列化器 Serializer
from rest_framework import serializers
# 声明序列化器,所有的序列化器都要直接或者间接继承于 Serializer
class StudentSerializer(serializers.Serializer):
"""商品信息序列化器"""
name = serializers.CharField()
price = serializers.IntegerField()
一,序列化时:没啥可说的,就是把模型对象转换成字典
二,反序列化时:
1,先判断接受的数据是否符合参数规则
2,符合规则的数据放入到validate_data中
3,修改表模型对象属性,手动操作,重写updata或create方法,因为Serializer没有提供这两个方法
def update (self,instance,validate_data):
instance.name=validate_data.get('name')
instance.price=validate_data.get('price')
instance.save() #表模型对象的save方法
def create(self,instance,validate_data):
models.Book.object.create(**validate_data)
4,调用序列化器的.save()方法内部会调用update或save方法,数据就存入表中了
三,反序列化的额外方法:
1)validators法:该方法将和校验函数配置在参数里
name = serializers.CharField(validators=[check_func])
def check_func(data):
业务逻辑代码
2)局部校验和全局校验两种方法:
局部校验钩子函数:函数命名规则--validate_字段名
def validate_price(self,data):
业务逻辑代码
全局校验钩子函数:函数命名规则--validate
def validate(self,validated_data):
业务逻辑代码
如果校验不通过就要抛出异常:
raise ValidationError('错误提示')
校验通过就返回数据
四,返回和接收的数据的字段不一样怎么办?参数中加入下面两个参数
name = serializers.CharField(read_only = True)
read_only = True #只读字段
write_only = True #只写字段
五,如何自定义返回查表结果?Serializer高级用法
# source的使用
1 可以改字段名字 xxx=serializers.CharField(source='title') #title是表中有的字段
2 可以跨表publish=serializers.CharField(source='publish.email')#跨表的前提是publish是 外键字段,而且email在publish表中
3 可以执行方法pub_date=serializers.CharField(source='test') #test是Book表模型中的方法
# SerializerMethodField()更强的自定义输出结果
1 它需要有个配套方法,方法名叫get_字段名,返回值就是要显示数据
authors=serializers.SerializerMethodField()
def get_authors(self,instance):
# book对象
authors=instance.authors.all() # 取出所有作者
ll=[] #编辑自定义的查询结果
for author in authors:
ll.append({'name':author.name,'age':author.age})
return ll
2.2 全自动序列化器ModelSerializer
提供了create()和update()方法,可以直接调用了,但是不会自动执行
(如果继承了UpdateModelMixin,CreateModelMixin,这两个类会去验证数据是否合法并调用create()和update()方法)
使用:
1.我们创建一个BookInfoSerializer
class BookInfoSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = BookInfo
fields = (name,)
model指明参照哪个模型类
fields指明为模型类的哪些字段生成
2.指定字段
#fields详解:
fields内可以填入有1(model字段),2(model中定义的方法),3(SerializerMethodField()字段),4(子序列化字段)
1)表模型对应的字段:直接序列化字段的内容,若是外键字段返回一个对象的打印结果,需要在表模型中重写 __str__方法
2)model中定义的方法:序列化方法的结果,一般用来定制外键字段输出的信息,
3)SerializerMethodField()字段 和2.1的使用方法一样,需要额外添加字段
4)子序列法 直接引用其他序列化器的结果,也需要额外添加字段
class BookInfoSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
authors=serializers.SerializerMethodField()
authors=AuthorSerializer() #子序列化需要添加的字段
class Meta:
model = BookInfo
fields = (name,authors,)
注意:不是实实在在存在表中的字段都需要设置为只读,否则写入时报错!
read_only_fields = ('id',)
3.添加额外参数 extra_kwargs
我们可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数
class BookInfoSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = BookInfo
fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
extra_kwargs = {
'bread': {'min_value': 0, 'required': True},
'bcomment': {'min_value': 0, 'required': True},
}
2.3 序列化器的使用
基本用法
基于APIView视图类的使用
1) 先查询出一个对象
from students.models import Student
student = Student.objects.get(id=3)
2) 构造序列化器对象
from .serializers import StudentSerializer
serializer = StudentSerializer(instance=student)
3)获取序列化数据
通过data属性可以获取序列化后的数据,是一个字典
serializer.data
# {'id': 4, 'name': '小张', 'age': 18, 'sex': True, 'description': '猴赛雷'}
说明:
1)用于序列化时,只传一个instance参数,默认第一个参数
2)用于反序列化时,只传入data参数
- 同时传入 instance,data字段进行修改操作
4)如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明
5)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如
serializer = AccountSerializer(account, context={'request': request})
基于GenericAPiView配合Mixin类的使用
见4.3
高级用法
1.重写serializer的validate方法,通过context参数将数据传入序列化类中,实现复杂的业务逻辑在序列化类里判断
2.重写create或update方法实现一次性操作多张表,或其他业务需求