• Django1.11序列化与反序列化


    django序列化与反序列化

    from rest_framwork import serializers

    serializers.ModelSerializer

    模型类序列化器,必须依据模型类创建序列化器

    • 基于模型类自动生成一系列字段
    • 包含默认的 crate()和update()

    定义ModelSerializer类

    定义序列化器

    • class BookInfoSerializer(serializer.ModelSerializer):
      class Meta:
      model = BookInfo
      filels = 'all'
      read_only_fields = ('id', 'readcount', 'commentcount')
      extra_kwargs = {
      'readcount': {'min_value': 0, 'required': True},
      'commentcount': {'max_value': 0, 'required': True},
      }
      • model,指明参照的那个模型类
      • fields ,指明为模型类的那些字段生成
        • fields = ‘all’表示所有字段
        • exclude = ('iamge',) 表示排除哪些字段
        • fields = ('id','name','readcount') 表示显示哪些字段
      • read_only_fields指明只读字段,即仅用于序列化输出的字段
      • extra_kwargs,为ModelSerializer添加或修改原有的选型参数
        • extra_kwargs = {
          'readcount': {'min_value': 0, 'required': True},
          'commentcount': {'max_value': 0, 'required': True},
          }

    serailizers.Serializer

    即可以为数据库模型类定义,也可以为非数据库模型类的数据定义

    定义Serializer类

    定义序列化器

    • class BookInfoSerializer(serializers.Serializers)
      id = serializers.IntegerField(label='ID', read_only=True)
    • 字段和选选项

    创建Serializer对象

    • s = BookInfoSerializer(instance=None, data=empty, **kwarg)
      • instance:使用数据库对象赋值,用于序列化
        data:字典类型数据,用于反序列化

    序列化

    • 将程序中的数据结构类型转换为其他类型(字典,JSON,XML)Django中将模型类转化为JSON
    • 基本使用
      • 获取需要序列化的对象
        • from book.models import BookInfo
          book = BookInfo.objects.get(id=4)
          • books = BookInfo.objects.all()
      • 构造序列化器对象
        • from book.serializers import BookInfoSerializer
          serializer = BookInfoSerializer(instance=book)
          • serializer = BookInfoSerializer(instace=books, many=True)
      • 获取序列化数据
        • serializer.data
    • 关联对象嵌套序列化
      • 如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明
      • 关联的对象数据是一个
        • PrimaryKeyRelatedFiled
          • class PeopleInfoSerializer(serializers.Serializer):

      book = serializers.PrimaryKeyRelatedFiled(label='图书',read_only=True)

      book = serializers.PrimaryKeyRelatedFiled(label='图书',queryset=BookInfo.objects.all())
      * 包含read_only=True时,该字段不能用于反序列化使用
      * 包含queryset参数时,将被用作反序列化时参数校验使用
      * 使用序列化器对象的data方法时
      对应字段显示的是本表数据
      * {'id': 10, 'book': 3, 'description': '独孤九剑', 'gender': 1, 'name': '令狐冲'}
      * StringRelatedFiledd
      * 此字段被序列化为关联对象的字符串表示方式(即__str__方法的返回值)
      * book = serializers.StringRelatedFiled(label='图书')
      * class BookInfoSerializer(serializers.serializer):
      ...
      def str(self):
      return self.name
      * 使用序列化器对象的data方法时
      对应字段显示的关联表__str__方法返回的数据
      * {'description': '独孤九剑', 'name': '令狐冲', 'gender': 1, 'book': '笑傲江湖', 'id': 10}
      * 使用关联对象的序列化器
      * book = BookInfoSerializer()
      * 使用序列化器对象的data方法时
      对应字段显示的式OrderDict对象=有序字典
      * {'book': OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 28), ('commentcount', ('image', None)]), 'gender': 1, 'name': '令狐冲', 'description': '独孤九剑', 'id': 10}
      • 关联对象的数据是多个
        • many参数
        • 使用django创建模型类的时候,一对多的一表有peopleinfo_set隐藏字段
        • 如果关联对象的数据不是只有一个,而是包含多个数据,如想序列化对应数据时,此时关联字段类型的指明仍使用上述方法,只是在声明关联字段时,多补充一个many=True参数即可
          • class BookInfoSerializer(serializers.Serializer):
            peopleinfo_set = serializers.PrimarykeyRelatedField(read_only=True,many=True)
    • from book.models import BookInfo

    from book.serializers import BookInfoSerializer
    book = BookInfo.objects.get(id=3)
    serializer = BookInfoSerializer(book)
    serializer.data
    {'id': 3, 'peopleinfo_set': [10, 11, 12, 13], 'commentcount': 18, 'name': '笑傲江湖', 'readcount': 28, 'pub_date': '199-24', 'image': None}

    反序列化

    • 与序列化相反,Django中将JSOn字符串转化为Django中的模型类对象
    • 验证数据
      • from book.serializers import BookInfoSerializer

    data = {'pub_date':123}
    serializer = BookInfoSerializer(data=data)
    serializer.is_valid()
    False

    serializer.errors
    {'pub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')], 'name': [ErrorDetail(string='This field is required.', code='required')]}

    serializer.validated_data
    {}

    * 使用序列化器进行反序列化时,需要对数据进行验证后,才能获取
    

    验证成功的数据或保存成模型类对象
    * 序列化器对象调用is_valid()
    * 通过字段类型和选型验证,验证成功返回True,失败返回False
    * is_valid(raise_exception=True)
    * 验证失败后抛出serializers.ValidationError
    * 向前端返回HTTP 400 Bad Request响应
    * 自定义验证方法
    * validate_<field_name>
    * 在序列化器中定义固定方法,验证单一字段
    * class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增
    def validate_readcount(self,value):
    if value < 0:
    raise serializers.ValidationError('阅读数量不能为负数')
    return value
    * validate
    * 在序列化器中定义固定方法,验证多个字段
    * class BookInfoSerializer(serializers.Serializer):
    id = serializers.IntegerFiled(label='ID',read_only=True)
    readcount = serializers..IntegerFiled(label='阅读量',required=False)
    commentcount = serializers..IntegerFiled(label='评论量',required=False)
    def validate(self,attrs):
    readcount = attrs.get('readcount')
    commentcount = attrs['commentcount']
    if commentcount > readcount:
    raise serializers.ValidationError('评论量不能大于阅读量')
    returen attrs
    * validators
    * 在字段中添加validators选项参数,补充验证行为
    * class BookInfoSerializer(serializers.Serializer):

    def custom_validate(value):
        raise serializers.ValidationError('我就是来捣乱的')
    
    """图书数据序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='名称', max_length=20,validators=[custom_validate])
    pub_date = serializers.DateField(label='发布日期', required=False)
    readcount = serializers.IntegerField(label='阅读量', required=False)
    commentcount = serializers.IntegerField(label='评论量', required=False)
    image = serializers.ImageField(label='图片', required=False)
    peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)  # 新增
    * 序列化器对象调用errors
        * 验证失败获取错误信息
        * 验证成功,获取错误信息
    * 序列化器调用validated_data
        * 验证成功获取数据
    
    • 保存

      • 如果在验证成功后,想要基于validated_data完成数据对象的创建,可以通过实现create()和update()两个方法来实现。
        • class BookInfoSerializer(serializers.Serializer):

      """图书数据序列化器"""
      id = serializers.IntegerField(label='ID', read_only=True)
      name = serializers.CharField(label='名称', max_length=20)
      pub_date = serializers.DateField(label='发布日期', required=False)
      readcount = serializers.IntegerField(label='阅读量', required=False)
      commentcount = serializers.IntegerField(label='评论量', required=False)
      image = serializers.ImageField(label='图片', required=False)
      peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增

      def create(self, validated_data):
      """新建"""
      return BookInfo(**validated_data)

      def update(self, instance, validated_data):
      """更新,instance为要更新的对象实例"""
      instance.name = validated_data.get('name', instance.name)
      instance.pub_date = validated_data.get('pub_date', instance.pub_date)
      instance.readcount = validated_data.get('readcount', instance.readcount)
      instance.commentcount = validated_data.get('commentcount', instance.commentcount)
      return instance

      • 如果需要在返回数据对象的时候,也将数据保存到数据库中,则可以进行如下修改
        • class BookInfoSerializer(serializers.Serializer):

      """图书数据序列化器"""
      id = serializers.IntegerField(label='ID', read_only=True)
      name = serializers.CharField(label='名称', max_length=20)
      pub_date = serializers.DateField(label='发布日期', required=False)
      readcount = serializers.IntegerField(label='阅读量', required=False)
      commentcount = serializers.IntegerField(label='评论量', required=False)
      image = serializers.ImageField(label='图片', required=False)
      peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增

      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)
      instance.pub_date = validated_data.get('pub_date', instance.pub_date)
      instance.readcount = validated_data.get('readcount', instance.readcount)
      instance.commentcount = validated_data.get('commentcount', instance.commentcount)
      instance.save()
      return instance

      • 实现了上述两个方法后,在反序列化数据的时候,就可以通过save()方法返回一个数据对象实例了
        • serializer.save()
        • 如果创建序列化器对象的时候,没有传递instance实例,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,则调用save()方法的时候,update()被调用。

    XMind: ZEN - Trial Version

  • 相关阅读:
    java JSONObject
    android 8.0 悬浮窗 最简demo
    使用adb 命令(atrace)抓起systrace的方法。
    使用python处理selenium中的获取元素属性
    使用adb/Linux获取网关ip
    Requests text乱码
    python-uiautomator2
    adb命令 判断锁屏
    缓存穿透、缓存击穿与缓存雪崩
    ReentrantLock重入锁详解
  • 原文地址:https://www.cnblogs.com/serpent/p/9719671.html
Copyright © 2020-2023  润新知