Django-restframework17 Serializer

Django Rest Framework的序列化器(Serializer)允许将复杂数据转换为Python原生数据类型,支持JSON、XML等格式。序列化器包含ModelSerializer,提供方便的模型实例和queryset处理。它包含验证、部分更新、嵌套对象处理等功能。反序列化时,数据需经过验证才能保存。此外,HyperlinkedModelSerializer使用超链接处理关系,ListSerializer处理多个对象,BaseSerializer作为基础类支持自定义序列化和反序列化。
摘要由CSDN通过智能技术生成

1 Serializers

1 简介

序列化器允许将诸如queryset和模型实例之类的复杂数据转换为原生的Python数据类型,这些数据类型可以很容易地转换为JSON、XML或其他内容类型。序列化器还提供反序列化,允许解析后的数据在第一次验证传入数据之后被转换回复杂类型。
REST框架中的序列化器与Django的表单和模型类的工作非常相似。框架提供了一个Serializer类,使用一种强大的、通用的方法来控制响应的输出,和一个ModelSerializer类,它为创建处理模型实例和queryset的序列化器提供了一个有用的快捷方式。

2 使用示例

1.创建一个对象
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()

comment = Comment(email='leila@example.com', content='foo bar')
2. 声明一个serializer类,提供序列化和反序列化方法
from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()
3. 序列化对象(转化为python的原生数据类型,再转化为其他格式)
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"}'
4. 反序列化对象(首先将数据流转化为python原生数据)
from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser

# 转化成数据流
stream = BytesIO(json)
# 使用json解析器转化成python原生数据类型,从字符串中解析出json对象
data = JSONParser().parse(stream)
# 将这些原生数据恢复到验证字典中
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)}
5. 保存实例

如果我们想返回一个完整的对爱实例,那么我们必须基于validated data实现一个.create()或update()方法,或者两个都实现

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

如果对象与数据模型一致,也想保存对象到数据库模型中:

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

最后我们对通过验证的对象进行保存

comment = serializer.save()

.save()方法到底是更新还是创建,取决于我们是否传入一个已经存在的序列化实例,如:

# .save()将会创建一个新的实例
serializer = CommentSerializer(data=data)

# .save()将会更新已经存在的comment实例
serializer = CommentSerializer(comment, data=data)

保存时添加附加属性
有时,您希望您的视图代码能够在保存实例的时候注入额外的数据。这些额外的数据可能包括当前用户、当前时间或其他不属于请求数据的信息。

serializer.save(owner=request.user)

添加的附加信息也会被包含在validated_data中,然后传入到.create()或update()函数中去
重写保存方法
有时created()和update()方法名字命名不能传达出实际意义,就需要重写,如下, 你应该重写方法:

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)
6.验证

在反序列化数据时,在获取validated_data或保存实例前需要调用is_valid()方法,如果验证时发生了错误,serializer.errors将会包含发生的错误信息:

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也会列出具体的字段信息,可以通过
框架设置NON_FIELD_ERRORS_KEY来设置non_field_errors的字段名。
对于验证不合法的数据也可以抛出异常,设置raise_exception=True.

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

单个字段验证
添加.validate_方法(类似.clean_方法),如

from rest_framework import serializers

# 博客提交时的标题必须含有‘django’
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

如果字段设置了required=False,而且提交的时候没有包含这个字段,那么就不会被验证
如果需要对多个字段的值进行比较验证,应该重写.validate()方法,返回validated values或抛出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[
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆豆orz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值