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 = emailself.content = contentself.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 类中声明它们来包含的,如下所示:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/67423.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无需租用云服务器:使用Linux本地搭建web服务并实现内网穿透发布公网访问的详细教程

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 前言 在web项目中,部署的web站点需要被外部访问,则…

NoSQL:非关系型数据库分类

NoSQL&#xff0c;全称 Not Only SQL&#xff0c;意为不仅仅是 SQL&#xff0c;泛指非关系型数据库。NoSQL 是基于键值对的&#xff0c;而且不需要经过 SQL 层的解析&#xff0c;数据之间没有耦合性&#xff0c;性能非常高。 非关系型数据库又可细分如下&#xff1a; 键值存储…

前端自动化部署,Devops,CI/CD

DevOps 提到 Jenkins&#xff0c;想到的第一个概念就是 CI/CD 在这之前应该再了解一个概念。 DevOps Development 和 Operations 的组合&#xff0c;是一种方法论&#xff0c;并不特指某种技术或者工具。DevOps 是一种重视 Dev 开发人员和 Ops 运维人员之间沟通、协作的流程。…

前端包管理器:深入理解npm和yarn

引言 前端开发者们都知道&#xff0c;包管理器是我们日常开发中不可或缺的工具。在本文中&#xff0c;我们将深入探讨两个最常用的前端包管理器&#xff1a;npm (Node Package Manager) 和 Yarn。我们将通过一步步的操作&#xff0c;详细解释如何使用这两种工具&#xff0c;以…

Java on VS Code 8月更新|反编译器用户体验优化、新 Maven 项目工作流、代码高亮稳定性提升

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code for Java 的 8 月更新&#xff01;在这篇博客中&#xff0c;我们将为您提供有关反编译器支持的更多改进。此外&#xff0c;我们将展示如何创建没有原型的 Maven 项目以及一…

TensorFlow是什么

TensorFlow是一个开源的深度学习框架&#xff0c;由Google开发&#xff0c;用于构建和训练神经网络。它提供了一种简单而灵活的方法来构建各种类型的机器学习模型&#xff0c;包括卷积神经网络、循环神经网络、深度神经网络等。TensorFlow使用图和张量的概念来描述计算流程。 …

【C语言】字符函数,字符串函数,内存函数

大家好&#xff01;今天我们来学习C语言中的字符函数&#xff0c;字符串函数和内存函数。 目录 1. 字符函数 1.1 字符分类函数 1.2 字符转换函数 1.2.1 tolower&#xff08;将大写字母转化为小写字母&#xff09; 1.2.2 toupper&#xff08;将小写字母转化为大写字母&…

SpringMVC之入门

目录 1.SpringMVC工作流程 2.SpringMVC核心组件 2.1 DispatcherServlet 2.2 HandlerMapping 2.3 Handler 2.4 HandlerAdapter 2.5 ViewResolver 2.6 View 3.SpringMVC的入门 3.1 添加相关依赖 3.2 创建Spring-mvc.xml 3.3 配置web.xml 3.4 效果演示 4.静态资源处…

ios 运行ipa包 日志查看方式

方法一&#xff1a; 使用ideviceinstaller工具 # 安装ipa命令 brew install ideviceinstaller ideviceinstaller -i xxx.ipa# 查看运行日志 idevicesyslog# idevicesyslog 查找命令 idevicesyslog | grep test -A 3 -B 2 # 输出关键字所在行后3行&#xff0c;前2行) idevic…

每日一道面试题之什么是上下文切换?

上下文切换是指在计算机操作系统中&#xff0c;当多个进程或线程同时运行时&#xff0c;系统需要将当前运行进程或线程的状态&#xff08;包括程序计数器、寄存器值、内存映像等&#xff09;保存起来&#xff0c;然后切换到另一个进程或线程继续执行的过程。上下文切换通常由操…

GeoServe Web管理界面远程访问GeoServe Web管理界面的最佳工具

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址 前言 GeoServer是OGC Web服务器规范的J2EE实现&#xff0c;利用GeoServer可以方便地发布地图数据&#xff0c;允许用户对要素数据进行更新、删除、插入…

5 | Java Spark WordCount打成Jar 包测试

步骤 1:准备 WordCount 代码 首先,确保 编写了 WordCount 代码,已经提供了正确的输入文件路径。 package com.bigdata;import org.apache.spark.SparkConf; import org.apache.spark.api.java.

golang操作数据库--gorm框架、redis

目录 1.数据库相关操作(1)非orm框架①引入②初始化③增删改查 (2) io版orm框架 (推荐用这个)①引入②初始化③增删改查④gorm gen的使用 (3) jinzhu版orm框架①引入②初始化③增删改查 2.redis(1)引入(2)初始化①普通初始化②v8初始化③get/set示例 1.数据库相关操作 (1)非orm…

AJAX学习笔记4解决乱码问题

AJAX学习笔记3练习_biubiubiu0706的博客-CSDN博客 在Tomcat10来说,AJAX GET或者POST接收响应都不存在乱码问题 对于Tomcat9来说 前端测试代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>测试A…

数据库-多表查询

概述&#xff1a; 介绍&#xff1a;多表查询&#xff1a;指从多张表中查询数据 笛卡儿积&#xff1a;笛卡儿积是指在数学中&#xff0c;两个集合&#xff08;A集合和B集合&#xff09;的所有组合情况&#xff08;在多表查询时&#xff0c;需要消除无效的笛卡儿积&#xff09; 分…

excel中的引用与查找函数篇1

1、COLUMN(reference)&#xff1a;返回与列号对应的数字 2、ROW(reference)&#xff1a;返回与行号对应的数字 参数reference表示引用/参考单元格&#xff0c;输入后引用单元格后colimn()和row()会返回这个单元格对应的列号和行号。若参数reference没有引用单元格&#xff0c;…

传输层—TCP原理详解

目录 前言 1.TCP协议 2.TCP协议段格式 3.如何解包如何分用 4.网络协议栈和文件的关系 5.如何理解TCP报头 6.TCP的特点 7.TCP字段 7.1 16位窗口大小 7.2标志位 8.超时重传 9.连接管理机制 10.滑动窗口 11.拥塞控制 12.延迟应答 13.捎带应答 14.理解TCP的面向字…

【C++】Visual Studio EditorConfig 格式设置

【C】Visual Studio EditorConfig 格式设置 文章目录 【C】Visual Studio EditorConfig 格式设置I - EditorConfig1.1 - 通用设置indent_styleindent_sizetab_widthend_of_linecharsettrim_trailing_whitespaceinsert_final_newline II - Visual Studio 特定键值缩进设置cpp_in…

蚂蚁集团SQLess 开源,与内部版有何区别?

当我们使用关系型数据库时&#xff0c;SQL 是联系起用户和数据库的一座桥梁。 SQL 是一种高度非过程化的语言&#xff0c;当我们在编写SQL 时&#xff0c;表达的是想要什么数据&#xff0c;而不是怎么获取数据。因此&#xff0c;我们往往更关心SQL 有没有满足业务逻辑&#xff…