昨天, 我们完成了 Serializer 序列化器的反序列化操作, 那么今天我们就来学习 Serializer 序列化器的最后一点知识, 反序列化操作.
首先, 我们定要明确什么是反序列化操作?
反序列化操作: JOSN 数据 --> 字典数据 -->验证通过的字典数据 --> 模型数据
我们在进行反序列化操作时, 首先要保证就是拿到的字典数据一定要通过认证.
反序列化操作的步骤:
1. 定义一个序列化器(这里我们采用昨天定义好的序列化器即可).
- class BookInfoSerializer(serializers.Serializer):
- '''定义图书序 Serializer 序列化器'''
- # 这里的字段需要和模型类中的字段名, 字段类型, 约束一致
- id = serializers.IntegerField(label='ID', read_only=True)
- btitle = serializers.CharField(label='名称', max_length=20)
- bpub_date = serializers.DateField(label='发布日期', required=False)
- bread = serializers.IntegerField(label='阅读量', required=False)
- bcomment = serializers.IntegerField(label='评论量', required=False)
2. 准备 JSON 数据或字典数据
data = {'btitle':'大话西游','bpub_date':'2020-02-06'}
3. 验证字典数据
我们使用序列化器对象点出 is_valid()方法进行验证, 验证成功返回 True, 否则返回 False.
3.1 验证通过
当字典数据通过校验时, 我们可以通过序列化器对象点出 validated_data 属性获取到校验成功后的字典数据.
- >>> data = {
- 'btitle':'大话西游','bpub_date':'2020-02-06'
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- True
- >>> s.validated_data
- OrderedDict([('btitle', '大话西游'), ('bpub_date', datetime.date(2020, 2, 6))])
3.2 验证未通过
当字典数据未通过校验时, 我们可以通过序列化器对象点出 errors 属性获取到错误信息.
- >>> data = {
- 'bpub_date': 123
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- False
- >>> s.validated_data
- {
- }
- >>> s.errors
- {
- 'btitle': [ErrorDetail(string='This field is required.', code='required')], 'bpub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY-MM-DD.', code='invalid')]
- }
3.3 对单一字段进行验证
我们需要在序列化器类中定义一个名字为 (validate_字段名) 的方法, 来补充验证逻辑.
- def validate_btitle(self, value):
- '''
- 对 btitle 字段进行验补充
- :param value: 前段传递的 btitle 数据
- :return: 验证成功: 返回 value; 验证失败: 返回错误信息
- '''
当验证失败时, 我们使用 raise 抛出异常的方式来返回错误信息.
例如:
- # 补充单一字段的验证逻辑
- def validate_btitle(self, value):
- '''
- 对 btitle 字段进行验补充
- :param value: 前段传递的 btitle 数据
- :return: 验证成功: 返回 value; 验证失败: 返回错误信息
- '''
- # 验证逻辑
- if 'django' not in value:
- # 失败
- raise serializers.ValidationError('btitle 数据错误信息')
- # 成功
- return value
Shell 测试代码:
- >>> from booktest.serializers import BookInfoSerializer
- >>> data = {
- 'btitle': 'python'
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- False
- >>> s.errors
- {
- 'btitle': [ErrorDetail(string='btitle 数据错误信息', code='invalid')]
- }
- >>> data = {
- 'btitle': 'python_django'
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- True
- >>> s.validated_data
- OrderedDict([('btitle', 'python_django')])
3.4 对所有字段进行扩展验证
我们需要在序列化器中定义一个名字为 (validate()) 的方法, 来补充对所有字段进行扩展验证的逻辑.
- def validate(self, attrs):
- '''
- 对多个字段进行验证
- :param attrs: 前段传递的字典数据
- :return: 验证成功: 返回 attrs; 验证失败: 返回错误信息
- '''
同样, 我们也需要使用 raise 抛出异常信息.
例如:
- def validate(self, attrs):
- '''
- 对多个字段进行验证
- :param attrs: 前段传递的字典数据
- :return: 验证成功: 返回 attrs; 验证失败: 返回错误信息
- '''
- # 验证逻辑: 这里需要验证的是 bread 大于 bcomment
- bread = attrs.get('bread')
- bcomment = attrs.get('bcomment')
- if bread <bcomment:
- # 失败
- raise serializers.ValidationError('bread 需要大于 bcomment')
- # 成功
- return attrs
Shell 测试代码:
- >>> from booktest.serializers import BookInfoSerializer
- >>> data = {
- 'btitle': 'about django', 'bread': 10, 'bcomment': 20
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- False
- >>> s.errors
- {
- 'non_field_errors': [ErrorDetail(string='bread 需要大于 bcomment', code='invalid')]
- }
- >>> data = {
- 'btitle': 'about django', 'bread': 50, 'bcomment': 20
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- True
- >>> s.validated_data
- OrderedDict([('btitle', 'about django'), ('bread', 50), ('bcomment', 20)])
4. 验证后的字典数据 ---> 模型数据
这里, 我们已将到了数据反序列化的最后一步操作了.
同样, 我们也应该知道, 将验证后的字典数据转模型数据的实质, 其实就是将验证过的字典数据添加到数据库中.
那么, 对于将数据保存到数据库中的操作一共就两种: 一种是添加数据的操作, 一种是修改数据的操作.
4.1 添加数据
我们, 想要添加数据, 就需要在序列化器类中定义一个 create()方法.
- def create(self, validated_data):
- '''
- 序列化器进行新增数据的方法
- :param validated_data: 通过验证的字典数据
- :return: 根据 RESTful 设计方式, 需要将添加的数据返回
- '''
return ORM 添加数据的语句(模型类. objects.create(**validated_data))
例如:
- def create(self, validated_data):
- '''
- 序列化器进行新增数据的方法
- :param validated_data: 通过验证的字典数据
- :return: 根据 RESTful 设计方式, 需要将添加的数据返回
- '''
- return BookInfo.objects.create(**validated_data)
在这里, 我们需要返回添加的数据给前端, 因为我们定义的 API 是遵守 RESTful 设计风格的.
Shell 测试代码:
- >>> from booktest.serializers import BookInfoSerializer
- >>> data = {
- 'btitle': 'django 手册', 'bpub_date': '2020-02-05', 'bread': 20, 'bcomment': 10
- }
- >>> s = BookInfoSerializer(data=data)
- >>> s.is_valid()
- True
- >>> s.save()
- <BookInfo: django 手册>
注意:
当我们创建序列化对象时, 只传递 data 数据, 就表示我们需要向数据库里添加数据.
所以, 当序列化器对象调用 save()方法时, 会自动调用序列化器类中的 create()方法.
4.2 修改数据
我们, 想要修改数据时, 需要在序列化器类中定义一个 update()方法.
- def update(self, instance, validated_data):
- '''
- 序列化器进行修改数据的方法
- :param instance: 需要修改的模型对象
- :param validated_data: 前端传递的字典数据
- :return: 根据 RESTful 设计方式, 需要将修改的数据返回
- '''
- # 新值覆盖旧值
instance. 字段名 = validated_data.get(字段名)
- instance.save()
- return instance
例如:
- def update(self, instance, validated_data):
- '''
- 序列化器进行修改数据的方法
- :param instance: 需要修改的模型对象
- :param validated_data: 前端传递的字典数据
- :return: 根据 RESTful 设计方式, 需要将修改的数据返回
- '''
- # 新值覆盖旧值
- instance.btitle = validated_data.get('btitle')
- instance.bpub_date = validated_data.get('bpub_date')
- instance.bread = validated_data.get('bread')
- instance.bcomment = validated_data.get('bcomment')
- instance.save()
- return instance
我们同样也需要将修改的数据返回给前端.
Shell 测试代码:
- from booktest.models import BookInfo
- from booktest.serializers import BookInfoSerializer
- >>> book = BookInfo.objects.get(id=10)
- >>> data = {
- 'btitle': 'python_django 手册', 'bpub_date': '2020-02-05', 'bread': 20, 'bcomment': 10
- }
- >>> s = BookInfoSerializer(instance=book,data=data)
- >>> s.is_valid()
- True
- >>> s.save()
- <BookInfo: python_django 手册>
注意:
当我们创建序列化器对象时, 传递了 instance 和 data 数据, 就表示我们需要进行数据的修改操作.
所以, 当我们使用序列化器对象调用 save()方法时, 会自动调用序列化器类中的 update()方法.
至此, 我们的 Serializer 序列化的反序列化操作就学习完毕了.
序列化器的学习中, 几乎没有什么逻辑点, 因为, 使用的是他人已经封装好的框架, 所以必须遵守框架的规定来开发, 只需要, 记住模版即可.
来源: https://www.cnblogs.com/chao666/p/12269977.html