zoukankan      html  css  js  c++  java
  • rest框架-- serializer操作

    Serializers把querysets和model instances这些复杂的数据结构转化为native Python 以便于以json,xml或其它内容类型的形式render出去。

    • 类似于Django的 Form 和ModelForm
    • Serializer和ModelSerializer

    序列化对象
    from datetime import datetime
    
    classComment(object):def __init__(self, email, content, created=None):self.email = email
            self.content = content
            self.created = created or datetime.now()
    from rest_framework import serializers
    
    classCommentSerializer(serializers.Serializer):
        email = serializers.EmailField()
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()
    comment =Comment(email='leila@example.com', content='foo bar')
    serializer =CommentSerializer(comment)
    serializer.data
    # {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

    把数据转化为json格式

    from rest_framework.renderers importJSONRenderer
    
    json =JSONRenderer().render(serializer.data)
    json
    # b'{"email":"leila@example.com","content":"foo bar","created":"2016-01-27T15:17:10.375877"}'

    反序列化对象

    把json数据转化为本地数据类型,也就是Django rest framework可以使用的数据类型

    from django.utils.six importBytesIOfrom rest_framework.parsers importJSONParser
    
    stream =BytesIO(json)
    data =JSONParser().parse(stream)

    让后进一步把这些数据绑定到serializers上面,serializer = CommentSerializer(data=data)之后使用serializer.is_valid()验证传进来的数据(上段代码的data是否符合CommentSerializer的格式,这里可以写一个try-exception.现在可以在serializer.validated_data找到传进来的数据。
    在访问validated data或板寸validated data之前一定要检查serializer.is_valid()是否为true。如果为false的话错误信息包含在serializer.errors里。

    serializer =CommentSerializer(data=data)
    serializer.is_valid()# True
    serializer.validated_data
    # {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)}

    保存instances

    我们应该实现基本的create和update方法,把数据写入数据库

    def create(self, validated_data):
    
      returnComment.objects.create(**validated_data)
    
    def update(self, instance, validated_data):
            instance.email = validated_data.get('email', instance.email)
            instance.content = validated_data.get('content', instance.content)
            instance.created = validated_data.get('created', instance.created)
            instance.save()return instance

    如果不需要写入数据库,可以直接放回数据就好了

    classCommentSerializer(serializers.Serializer):
        email = serializers.EmailField()
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()def create(self, validated_data):returnComment(**validated_data)
    
      def update(self, instance, validated_data):
            instance.email = validated_data.get('email', instance.email)
            instance.content = validated_data.get('content', instance.content)
            instance.created = validated_data.get('created', instance.created)
    
         return instance

    在命令行中的编写如下:
    创建一个新的对象

    serializer =CommentSerializer(data=data)
    serializer.is_valid()# True
    serializer.validated_data
    # {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)}
    comment = serializer.save()

    更新已经存在的comment实例

    serializer =CommentSerializer(comment, data=data)
    serializer.is_valid()# True
    serializer.validated_data
    # {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)}
    comment = serializer.save()

    在save的时候添加其它内容比如

    serializer.save(owner=request.user)

    owner数据被绑定在serializer.validated_data对象上,当create或update的时候就会被添加进数据库。
    直接重写save()方法
    有时候并不需要保存或则返回数据,这个时候save()方法就需要重写。比如执行发送邮件的任务。

    classContactForm(serializers.Serializer):
        email = serializers.EmailField()
        message = serializers.CharField()def save(self):
            email =self.validated_data['email']
            message =self.validated_data['message']
            send_email(from=email, message=message)

    请注意,在上述情况下,我们现在必须直接访问serializer_date属性。


    验证
    serializer =CommentSerializer(data={'email':'foobar','content':'baz'})
    serializer.is_valid()# False
    serializer.errors
    # {'email': [u'Enter a valid e-mail address.'], 'created': [u'This field is required.']}

    non_field_errors关键字有可能出现,可以在REST framework 框架的设置文件里面设置NON_FIELD_ERRORS_KEY。
    is_valid()有默认的异常处理机制,raise_exception标志默认为true,框架自动帮你抛异常(serializers.ValidationError)。

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

    自定义验证
    类似于Django表单的clean_<fieldname>方法,你可以添加validate<field_name>方法到你的Serializer子类里面。这个方法只接受要验证的数据这一个对象。抛出的异常也是serializers.ValidationError。

    from rest_framework import serializers
    
    classBlogPostSerializer(serializers.Serializer):
        title = serializers.CharField(max_length=100)
        content = serializers.CharField()
    
      def validate_title(self, value):"""
            Check that the blog post is about Django.
            """if'django'notin value.lower():raise serializers.ValidationError("Blog post is not about Django")return value

    注意:如果你不希望这个验证方法被使用,你可以在serializer上声明required=False,那么如果这个field没有包括进来这个验证步骤就不会起作用。(这里有点不清晰)
    对象级验证
    如果你的验证需要访问多个fileds,你可以添加serializer的子类validate().这个方法接收一个字典参数,你需要使用的多个fileds应该包含在这个字典参数里面。报错类型为serializers.ValidationError

    from rest_framework import serializers
    
    classEventSerializer(serializers.Serializer):
        description = serializers.CharField(max_length=100)
        start = serializers.DateTimeField()
        finish = serializers.DateTimeField()
    
      def validate(self, data):"""
            Check that the start is before the stop.
            """if data['start']> data['finish']:raise serializers.ValidationError("finish must occur after start")return data

    验证器

    • 通过在字段实例上声明使用验证器
    def multiple_of_ten(value):
    
       if value %10!=0:
    
       raise serializers.ValidationError('Not a multiple of ten')classGameRecord(serializers.Serializer):
    score =IntegerField(validators=[multiple_of_ten])...
    • 作用于全部字段的验证器
      下载Meta里面
    classEventSerializer(serializers.Serializer):
        name = serializers.CharField()
        room_number = serializers.IntegerField(choices=[101,102,103,201])
        date = serializers.DateField()classMeta:# Each room only has one event per day.
            validators =UniqueTogetherValidator(
                queryset=Event.objects.all(),
                fields=['room_number','date'])
  • 相关阅读:
    MySql基础教程(三)——查询训练
    MySql基础教程(二)
    MySql基础教程(一)
    解决Eclipse闪退问题的方法总结
    MySQL图形工具 MySQL GUI Tools的安装使用方法
    MySql5.6版修改用户登录密码
    Windows下MySQL解压版的配置
    js 数组容易弄混的那些方法
    如何使CSS--better(系列二)
    如何使CSS--better(系列一)
  • 原文地址:https://www.cnblogs.com/52forjie/p/9705590.html
Copyright © 2011-2022 走看看