序列化器


序列化器:

作用:image-20210416101325153

序列化:

​ 数据之间的相互转换,数据结构类型转换为其他格式(字典,JSON,XML等),将Django的模型类对象转换为JSON字符串

反序列化:

​ 反之,将其他格式转换为程序整的数据,例如将JSON字符串转换为Django中的模型类对象

1.1定义:

能够参考模型序列化器:

"""
定义序列化器
1.定义类,继承自Serializer
2.和模型类,字段,类型,选项一样
    read_only=True 只读
    label 字段说明

"""

代码(book/serializers.py):

#1.定义序列化器
class BookInfoSerializer(serializers.Serializer):
    id = serializers.IntegerField(label='id',read_only=True)
    btitle = serializers.CharField(max_length=20, label='名称')
    bpub_date = serializers.DateField(label='发布日期')
    bread = serializers.IntegerField(default=0, label='阅读量')
    bcomment = serializers.IntegerField(default=0, label='评论数')
    is_delete = serializers.BooleanField(default=False, label='逻辑删除')

代码(book/model.py):

from django.db import models

#定义图书模型类
class BookInfo(models):
    btitle = models.CharField(max_length=20,verbose_name='名称')
    bpub_date = models.DateField(verbose_name='发布日期')
    bread = models.IntegerField(default=0,verbose_name='阅读量')
    bcomment = models.IntegerField(default=0,verbose_name='评论数')
    is_delete = models.BooleanField(default=False,verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_books' # 知名数据库名称
        verbose_name = '图书' #admin站点中显示的名称
        verbose_name_plural = verbose_name #显示的复数名称

    def __str__(self):
        '''定义每个数据对象的显示信息'''
        return self.btitle

1.2序列化器,序列化单个对象

​ 操作流程(book/view.py)


'''===========1.序列化器,序列化单个书籍对象==========='''
from .serializers import BookInfoSerializer
from .models import BookInfo

#1.获取书籍对象
book = BookInfo.objects.get(id=1)

#2.创建序列化器,instance,表示要序列化的对象
serializer = BookInfoSerializer(instance=book)

#3.转换数据
print(serializer.data)

'''
结果:
{'id': 1, 'btitle': '西游记', 'bpub_date': '2021-04-21', 'bread': 30, 'bcomment': 39, 'is_delete': False}
'''

注意点:
BookInfoSerializer(instance=book)

​ instance=book:表示将book序列化

​ serializer.data:获取序列化的结果

序列化器,序列化列表

​ 操作流程(book/view.py)

#1.获取书籍对象
books = BookInfo.objects.all()

#2.创建序列化器,instance,表示要序列化的对象,many=True 表示序列化多个对象
serializer = BookInfoSerializer(instance=books,many=True)

#3.转换数据
print(serializer.data)

'''
结果:
[OrderedDict([('id', 1), ('btitle', '西游记'), ('bpub_date', '2021-04-21'), ('bread', 30), ('bcomment', 39), ('is_delete', False)]),
 OrderedDict([('id', 2), ('btitle', '水浒传'), ('bpub_date', '2021-04-08'), ('bread', 40), ('bcomment', 30), ('is_delete', False)])]

'''
注意点:

​ BookInfoSerializer(instance=book,many=True)

​ many=True:表示序列化多个对象

英雄序列化器

​ 操作流程(book/serializers.py):

定义英雄序列化器:

class HeroInfoSerializer(serializers.Serializer):
    """英雄数据序列化器"""
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    id = serializers.IntegerField(label='ID', read_only=True)
    hname = serializers.CharField(label='名字', max_length=20)
    hgender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False)
    hcomment = serializers.CharField(label='描述信息', max_length=200, required=False, allow_null=True)


定义关联字段:

class HeroInfoSerializer(serializers.Serializer):
    ......
    
#1,添加外键,主键表示 必须提供`queryset` 选项, 或者设置 read_only=`True`.显示外键
    # hbook = serializers.PrimaryKeyRelatedField(queryset=BookInfo.objects.all())
    # hbook = serializers.PrimaryKeyRelatedField(read_only=True)
    # 结果:{'id': 1, 'hname': '吴承恩', 'hgender': 1, 'hcomment': '孙悟空', 'hbook': 1}

    #2,添加外键, 来自于关联模型类, __str__的返回值 外键名称
    # hbook = serializers.StringRelatedField(read_only=True)
    # 结果:{'id': 1, 'hname': '吴承恩', 'hgender': 1, 'hcomment': '孙悟空', 'hbook': '西游记'}

    #3,添加外键,关联另外一个序列化器 返回外键关联的所有信息
    hbook = BookInfoSerializer(read_only=True)
    # 结果:{'id': 1, 'hname': '吴承恩', 'hgender': 1, 'hcomment': '孙悟空', 'hbook': OrderedDict([('id', 1), ('btitle', '西游记'), ('bpub_date', '2021-04-21'), ('bread', 30), ('bcomment', 39), ('is_delete', False)])}
书籍序列化器,关联many

​ 目的:能够序列化书籍的时候,输出关联作者信息

​ 操作流程(book/serializers.py):

class BookInfoSerializer(serializers.Serializer):
    id = serializers.IntegerField(label='id',read_only=True)
    btitle = serializers.CharField(max_length=20, label='名称')
    bpub_date = serializers.DateField(label='发布日期')
    bread = serializers.IntegerField(default=0, label='阅读量')
    bcomment = serializers.IntegerField(default=0, label='评论数')
    is_delete = serializers.BooleanField(default=False, label='逻辑删除')

    #1.用书籍查作者:关联英雄主键,many=True,一方中,序列化多方需要加上 (获取id)
    # heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
    #2.关联英雄,__str__返回值(获取name)
    heroinfo_set = serializers.StringRelatedField(read_only=True,many=True)

​ 注意:

​ many=True,一方中,序列化多方需要加上

==============================================

反序列化

1.1数据类型验证

  • 目的:理解序列化器中的字段,对数据进行校验的过程

  • 常见的字段类型:

    1. CharField:字段串

    2. ······

1.2反序列化选项验证

image-20210419093003168

判断max_length等等

  • requred:默认是True,必须要传递,除非设置了 default | false | read_only
  • read_only: 只读,不进行反序列化

1.3反序列化单个字段验证 :

​ 目的:定义单个字段校验

class BookInfoSerializer(serializers.Serializer):
    ......
    
    
    
    # 反序列化单个字段校验 validate多字段校验,加上字段名是单个字段校验
    def validate_btitle(self, value):
         # 校验value的内容
         if '金瓶' not in value:
             raise  serializers.ValidationError('书籍不包含金瓶')
         return value
  • 注意点:
    • 固定格式:
      def validate_字段名称(self, value):
      • pass

1.4 反序列化,多个字段validate验证

  • 目的:

  • 代码展示:

  • #多字段校验
        def validate(self, attrs):
            """
            :param attrs: 外界传过来的,book_dict
            :return: 
            """
            #1.获取阅读量,评论量
            bread = attrs['bread']
            bcomment = attrs['bcomment']
            #2.判断
            if bcomment > bread:
                raise serializers.ValidationError('评论量大于阅读量')
            #返回:
            return attrs
    
  • 注意:

    • 校验不通过的时候一定要抛出异常

1.5反序列化,自定义验证方法

1.6 反序列化,create保存数据

  • 视图层:

    • from book.serializers import BookInfoSerializer
      # 1.准备数据
      book_dict = {
          "btitle":"金瓶x-插画版",
          "bpub_date":"2019-01-01",
          "bread":17,
          "bcomment":25
      }
      
      #2,创建序列化器,校验
      serializer = BookInfoSerializer(data=book_dict)
      
      # serializer.is_valid()
      
      serializer.is_valid(raise_exception=True) #校验不通过,直接报错
      # 3.输出
      serializer.save()
      
  • 序列化器代码

    • from rest_framework import serializers
      
      #1.定义序列化器
      from book.models import BookInfo
      class BookInfoSerializer(serializers.Serializer):
      ......
      
          #实现create方法
          def create(self, validated_data):
              '''
              :param validated_data: 校验成功子后的数据
              :return:
              '''
              #1.创建book对象,入库
              book = BookInfo.objects.create(**validated_data)
              #2.返回
              return book
      
  • 注意点:

    • 当使用序列化器调用sava方法的时候,执行的就是序列化器中的create方法

1.7 反序列化,update更新数据

  • 视图层:

    • '''===========3.序列化器,反序列化,update更新数据==========='''''
      
      from book.serializers import BookInfoSerializer
      from book.models import BookInfo
      # 1.准备数据
      book_dict = {
          "btitle":"水浒传",
          "bpub_date":"2019-01-01",
          "bread":50,
          "bcomment":25
      }
      #要更新的数据
      book = BookInfo.objects.get(id=1)
      #2,创建序列化器,校验
      serializer = BookInfoSerializer(instance=book,data=book_dict)
      
      
      serializer.is_valid(raise_exception=True) #校验不通过,直接报错
      # 3.入库
      serializer.save()
      
  • 序列化器代码:

    • from rest_framework import serializers
      
      #1.定义序列化器
      from book.models import BookInfo
      class BookInfoSerializer(serializers.Serializer):
      ......
      
         #实现update方法:
          def update(self, instance, validated_data):
              '''
      
              :param instance: 外界传过来的值
              :param validated_data: 验成功子后的数据
              :return:
              '''
      
              # 1.更新数据
              instance.btitle = validated_data['btitle']
              instance.bpub_date = validated_data['bpub_date']
              instance.bread = validated_data['bread']
              instance.bcomment = validated_data['bcomment']
      
              # 2.入库
              instance.save()
      
              return instance
      

总结:

image-20210419163100154*


文章作者: Kexuan Shi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Kexuan Shi !
评论
  目录