理解(重点)
- 序列化器 - Serializer类
class - 本质上是一个类,我们定义了它,就是来处理数据的,是独立于model数据库之外的存在(不要混淆)
- 序列化器对象 - Serializer对象
本质上就是上边那个类的一个实例,这个对象就是处理 序列化 和 反序列化 的枢纽核心,逻辑上面向的对象
# 序列化器对象 - 构造方法
serializer = Serializer(instance=None, data=empty, **kwarg)
说明:
1)用于序列化时,将模型类对象传入instance参数
2)用于反序列化时,将要被反序列化的数据传入data参数
3)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如
serializer = AccountSerializer(account, context={'request': request}) # account,其实就是 instance=account 位置参数
通过context参数附加的数据,可以通过Serializer对象的context属性获取
注意: partial
默认序列化器必须传递所有required的字段,否则会抛出验证异常
可以使用 partial 参数来允许部分字段更新(常用场景:修改对象数据,即调用save()方法时,使用序列化器的update方法)
serializer = BookInfoSerializer(instance=book, data={'pub_date': '2999-1-1'}, partial=True)
序列化的使用
- 基本使用
# 一条数据(一条记录)
book = BookInfo.objects.get(id=4)
serializer = BookInfoSerializer(book)
serializer.data # data属性,可以获取序列化后的数据
# 包含多条数据(多条记录)的查询集QuerySet,可以通过添加many=True参数,说明
books = BookInfo.objects.all()
serializer = BookInfoSerializer(books, many=True)
serializer.data
- 关联对象 - 嵌套序列化
以后具体在写
反序列化的使用
- 验证
异常处理:
is_valid()方法,还可以在验证失败时抛出异常serializers.ValidationError,可以通过传递raise_exception=True参数开启,
REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应
# 验证
# 在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False
serializer.is_valid(raise_exception=True)
# 验证 - 失败
# errors属性,获取错误信息,返回字典,包含了字段和相应字段的错误描述(key:value)
serializer.errors
# 验证 - 成功
# validated_data属性,获取校验后(反序列化)的数据 --- 此时的errors属性,是{},空字典
serializer.validated_data
- 保存
如果在验证成功后,想要基于validated_data,完成数据对象的创建/修改,可以通过实现create()和update()两个方法来实现
class BookInfoSerializer(serializers.Serializer):
... ...
def create(self, validated_data):
"""新建"""
return BookInfo.objects.create(**validated_data)
def update(self, instance, validated_data):
"""更新,instance为要修改的对象实例"""
instance.name = validated_data.get('name', instance.name) # 注意使用 get 获取字典中的数据,这样更新成功,则是新数据,更新失败,则还是原来的数据 instance.name
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.save()
return instance
实现了上述两个方法后,在反序列化数据的时候,就可以通过save()方法,返回一个数据对象实例了
# 视图中,调用 serializer 该序列化器对象的save()方法即可
book = serializer.save()
# 核心点 -- 创建序列化器对象的时候:
# 没有传递instance实例,调用save()方法的时候,create()被调用 -- 新建
# 传递了instance实例,则调用save()方法的时候,update()被调用 -- 修改
注意:
在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到
serializer.save(owner=request.user)