栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django rest framework之Serializers笔记(一)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django rest framework之Serializers笔记(一)

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

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

序列化对象
from datetime import datetime

class Comment(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

class CommentSerializer(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 import JSonRenderer

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 import BytesIO
from rest_framework.parsers import JSonParser

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):
 return Comment.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

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

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

    def create(self, validated_data):
 return Comment(**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()方法就需要重写。比如执行发送邮件的任务。

class ContactForm(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_方法,你可以添加validate方法到你的Serializer子类里面。这个方法只接受要验证的数据这一个对象。抛出的异常也是serializers.ValidationError。

from rest_framework import serializers

class BlogPostSerializer(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' not in 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

class EventSerializer(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')

class GameRecord(serializers.Serializer):
    score = IntegerField(validators=[multiple_of_ten])
    ...
  • 作用于全部字段的验证器
    下载meta里面
class EventSerializer(serializers.Serializer):
    name = serializers.CharField()
    room_number = serializers.IntegerField(choices=[101, 102, 103, 201])
    date = serializers.DateField()

    class meta:
 # Each room only has one event per day.
 validators = UniqueTogetherValidator(
     queryset=Event.objects.all(),
     fields=['room_number', 'date']
 )
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/223203.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号