zoukankan      html  css  js  c++  java
  • Python学习————反序列化器(复习)

    反序列化器

    数据验证

    使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
    
    在获取反序列化的数据前,必须调用**is_valid()**方法进行验证,验证成功返回True,否则返回False。
    
    验证失败,可以通过序列化器对象的**errors**属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改REST framework配置中的**NON_FIELD_ERRORS_KEY**来控制错误字典中的键名。
    
    验证成功,可以通过序列化器对象的**validated_data**属性获取数据。
    
    在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为。
    
    

    BookInfoSerializer

    class BookInfoSerializer(serializers.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)
        image = serializers.ImageField(label='图片', required=False)
    

    通过构造序列化器对象,并将要反序列化的数据传递给data构造参数,进而进行验证

    from booktest.serializers import BookInfoSerializer
    data = {'bpub_date': 123}
    serializer = BookInfoSerializer(data=data)
    serializer.is_valid()  # 返回False
    serializer.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')]}
    serializer.validated_data  # {}
    
    data = {'btitle': 'python'}
    serializer = BookInfoSerializer(data=data)
    serializer.is_valid()  # True
    serializer.errors  # {}
    serializer.validated_data  #  OrderedDict([('btitle', 'python')])
    

    is_valid()方法还可以再验证失败时抛出异常serizlizers.ValidationError 可以通过传递ralse_exception=True参数**开启,REST framwork借到磁异常,回想前端返回HTTP 400 Bad Request响应

    return a 400 response if the data was invalid.
    serializer.is_valid(raise_exception=True)
    

    validate_字段名

    对<field_name>字段进行验证,如

    class BookInfoSerializer(serializers.Serializer):
        """图书数据序列化器"""
        ...
    
        def validate_btitle(self, value):
            if 'django' not in value.lower():
                raise serializers.ValidationError("图书不是关于Django的")
            return value
    
    validate

    在序列化器中需要同时对多个字段进行比较验证时,可以定义validate方法来验证,如

    class BookInfoSerializer(serializers.Serializer):
        """图书数据序列化器"""
        ...
    
        def validate(self, attrs):
            bread = attrs['bread']
            bcomment = attrs['bcomment']
            if bread < bcomment:
                raise serializers.ValidationError('阅读量小于评论量')
            return attrs
    

    反序列化-保存数据

    前面的验证数据成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象.

    可以通过实现create()和update()两个方法来实现。

    class BookInfoSerializer(serializers.Serializer):
        """图书数据序列化器"""
        ...
    
        def create(self, validated_data):
            """新建"""
            return BookInfo(**validated_data)
    
        def update(self, instance, validated_data):
            """更新,instance为要更新的对象实例"""
            instance.btitle = validated_data.get('btitle', instance.btitle)
            instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
            instance.bread = validated_data.get('bread', instance.bread)
            instance.bcomment = validated_data.get('bcomment', instance.bcomment)
            return instance
    

    如果需要在返回数据对象的时候,也将数据保存到数据库中,则可以进行如下修改

    class BookInfoSerializer(serializers.Serializer):
        """图书数据序列化器"""
        ...
    
        def create(self, validated_data):
            """新建"""
            return BookInfo.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            """更新,instance为要更新的对象实例"""
            instance.btitle = validated_data.get('btitle', instance.btitle)
            instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
            instance.bread = validated_data.get('bread', instance.bread)
            instance.bcomment = validated_data.get('bcomment', instance.bcomment)
            instance.save()
            return instance
    

    实现了上述两个方法后,在反序列化数据的时候,就可以通过save()方法返回一个数据对象实例了

    book = serializer.save()
    

    如果创建序列化器对象的时候,没有传递instance实例,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,则调用save()方法的时候,update()被调用。

    from db.serializers import BookInfoSerializer
    data = {'btitle': '封神演义'}
    serializer = BookInfoSerializer(data=data)
    serializer.is_valid()  # True
    serializer.save()  # <BookInfo: 封神演义>
    
    from db.models import BookInfo
    book = BookInfo.objects.get(id=2)
    data = {'btitle': '倚天剑'}
    serializer = BookInfoSerializer(book, data=data)
    serializer.is_valid()  # True
    serializer.save()  # <BookInfo: 倚天剑>
    book.btitle  # '倚天剑'
    

    附加说明

    1) 在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到

    # request.user 是django中记录当前登录用户的模型对象
    serializer.save(owner=request.user)
    

    2)默认序列化器必须传递所有required的字段,否则会抛出验证异常。但是我们可以使用partial参数来允许部分字段更新

    # Update `comment` with partial data
    serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True)
    
  • 相关阅读:
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第50章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第49章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第48章 读书笔记(待更新)
    Spring Boot 中使用 Quartz 实现任务调度
    实战 FastDFS Java 客户端上传文件
    分布式文件系统之 FastDFS
    Java 持久层框架之 MyBatis
    C语言实现贪吃蛇
    [转载]分享三篇非常好的学习心得
    selenium加载cookie报错问题:selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cookie domain
  • 原文地址:https://www.cnblogs.com/x945669/p/13307902.html
Copyright © 2011-2022 走看看