Django REST framework中的序列化Serializers

这篇具有很好参考价值的文章主要介绍了Django REST framework中的序列化Serializers。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSON,XML 或其他内容类型。序列化器还提供反序列化,在首次验证传入数据之后,可以将解析的数据转换回复杂类型。
简单来说,服务器通过api 返回数据(json格式),把非json格式转换为json 就是序列化的过程
浏览器提交给服务器端的数据,服务端将json 格式转换给非json存储到数据库,就是反序列化

REST framework 中的序列化类与 Django 的 Form 和 ModelForm 类非常相似。我们提供了一个 Serializer 类,它提供了一种强大的通用方法来控制响应的输出,以及一个 ModelSerializer 类,它为创建处理模型实例和查询集的序列化提供了有效的快捷方式。

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')

声明一个序列化类,使用它来序列化和反序列化与 Comment 对象相对应的数据
声明一个序列化类看起来非常类似于声明一个表单:

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

2、序列化对象

现在可以使用 CommentSerializer 来序列化评论或评论列表。同样,使用 Serializer 类看起来很像使用 Form 类。

serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

此时已经将模型实例转换为 Python 原生数据类型。为了完成序列化过程,将数据渲染为 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"}'

3、反序列化对象

反序列化是相似的。首先我们将一个流解析为 Python 原生数据类型…

from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser
stream = BytesIO(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)}

4、保存实例

如果希望能够基于验证的数据返回完整的对象实例,则需要实现 .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

如果对象实例与 Django 模型相对应,还需要确保这些方法将对象保存到数据库。如果 Comment 是一个 Django 模型,这些方法可能如下所示:

 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

现在,当反序列化数据时,我们可以调用 .save() 根据验证的数据返回一个对象实例。

comment = serializer.save()

调用 .save() 将创建一个新实例或更新现有实例,具体取决于在实例化序列化类时是否传递了现有实例:

# .save() will create a new instance.
serializer = CommentSerializer(data=data)
# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)

.create() 和 .update() 方法都是可选的。您可以都不实现,或者实现其中的一个或两个,具体取决于你的序列化类的用例。

将附加属性传递给 .save()

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

serializer.save(owner=request.user)

调用 .create() 或 .update() 时,任何其他关键字参数都将包含在 validated_data 参数中。

直接覆盖 .save()。

在某些情况下,.create() 和 .update() 方法名称可能没有意义。例如,在 “联系人表单” 中,我们可能不会创建新实例,而是发送电子邮件或其他消息。

在这些情况下,可以选择直接覆盖 .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 .validated_data 属性。

5、验证

在反序列化数据时,你总是需要在尝试访问验证数据之前调用 is_valid(),或者保存对象实例。如果发生任何验证错误,那么 .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 (在 settings 文件中设置)来定制 non_field_errors 关键字的名称。

反序列化 item 列表时,错误将作为代表每个反序列化 item 的字典列表返回。

数据验证时抛出异常
.is_valid() 方法带有一个可选的 raise_exception 标志,如果存在验证错误,将导致它引发 serializers.ValidationError 异常。
这些异常由 REST framework 提供的默认异常处理程序自动处理,并且默认情况下将返回 HTTP 400 Bad Request

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

字段级验证
你可以通过向 Serializer 子类添加 .validate_<field_name> 方法来指定自定义字段级验证。这些与 Django 表单上的 .clean_<field_name> 方法类似。
这些方法只有一个参数,就是需要验证的字段值。

您的 validate_<field_name> 方法应返回验证值或引发 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

对象级验证
如果要对多个字段进行其他的验证,请将一个名为 .validate() 的方法添加到您的 Serializer 子类中。这个方法只有一个参数,它是一个字段值(field-value)的字典。如果有必要,它应该引发一个 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 类中声明它们来包含的,如下所示:文章来源地址https://www.toymoban.com/news/detail-706636.html

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']
        )

到了这里,关于Django REST framework中的序列化Serializers的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Django学习】(十)模型序列化器_关联字段序列化

    这篇文章是针对模型类序列化器以及如何关联字段序列化 进行深入讲解的;  在上面的模型序列化类中: 可以继承ModelSerializer类或者ModelSerializer的子类,来创建模型序列化器类; 模型序列化器类中可以重新定义序列化器字段,优先级大于自动生成的同名字段 如果新定义的字

    2024年02月11日
    浏览(46)
  • 【django2.0之Rest_Framework框架一】rest_framework序列器介绍

    Django RestFramework(简称DRF) 提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。 github地址: https://

    2024年02月07日
    浏览(42)
  • 【Django】Task4 序列化及其高级使用、ModelViewSet

    Task4主要了解序列化及掌握其高级使用,了解ModelViewSet的作用,ModelViewSet 是 Django REST framework(DRF)中的一个视图集类,用于快速创建处理模型数据的 API 视图。 Django 的序列化是指将复杂的数据结构(通常是数据库中的模型对象)转换为可以在不同应用程序间传输和存储的格

    2024年02月11日
    浏览(43)
  • java中的序列化和反序列化

    objectOutputStream 对象的序列化,以流的形式将对象写入文件 构造方法: objectOutputStream(OutputStream out) 传入一个字节输入流创建objectOutputStream对象 成员方法: void writeObject(object obj) 将指定的对象写入objectOutputStream 使用步骤: 创建一个类,这个类实现Serializable接口,Serializable是一

    2024年02月14日
    浏览(33)
  • 由Django-Session配置引发的反序列化安全问题

    漏洞成因位于目标配置文件settings.py下 关于这两个配置项 SESSION_ENGINE: 在Django中, SESSION_ENGINE  是一个设置项,用于指定用于存储和处理会话(session)数据的引擎。 SESSION_ENGINE  设置项允许您选择不同的后端引擎来存储会话数据,例如: 数据库后端  ( django.contrib.sessions.b

    2024年02月08日
    浏览(47)
  • Django实现接口自动化平台(九)环境envs序列化器及视图【持续更新中】

    相关文章: Django实现接口自动化平台(八)测试报告reports序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测试平台_做测

    2024年02月16日
    浏览(43)
  • Django实现接口自动化平台(八)测试报告reports序列化器及视图【持续更新中】

    上一章: Django实现接口自动化平台(七)数据库设计_做测试的喵酱的博客-CSDN博客 下一章: 官方文档: Serializers - Django REST framework apps/reports/serializers.py 1.1.1 代码解释: 1、  exclude: You can set the  exclude  attribute to a list of fields to be excluded from the serializer. For example: 2、read_o

    2024年02月09日
    浏览(44)
  • Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】

    相关文章: Django实现接口自动化平台(十二)自定义函数模块DebugTalks 序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测

    2024年02月17日
    浏览(40)
  • Django实现接口自动化平台(十一)项目模块Projects序列化器及视图【持续更新中】

    相关文章: Django实现接口自动化平台(十)自定义action names【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测试平台_做测试的喵酱的博

    2024年02月16日
    浏览(41)
  • 谈谈linux网络编程中的应用层协议定制、Json序列化与反序列化那些事

    由于socket api的接口,在读写数据的时候是以字符串的方式发送接收的,如果需要传输 结构化的数据 ,就需要制定一个协议 结构化数据在发送到网络中之前需要完成序列化 接收方收到的是序列字节流,需要完成反序列化才能使用(如ChatInfo._name) 当我们进行网络通信的的时

    2024年02月06日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包