zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/serpent/p/9719671.html
Copyright © 2011-2022 走看看