有关建设旅行网站的建设,盱眙县住房和城乡建设局网站,微信小程序开发工具,想招人去哪个平台免费序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型#xff0c;然后可以将它们轻松地呈现为 JSON#xff0c;XML 或其他内容类型。序列化器还提供反序列化#xff0c;在首次验证传入数据之后#xff0c;可以将解析的数据转换回复杂类型。 简单来…序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型然后可以将它们轻松地呈现为 JSONXML 或其他内容类型。序列化器还提供反序列化在首次验证传入数据之后可以将解析的数据转换回复杂类型。 简单来说服务器通过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, createdNone):self.email emailself.content contentself.created created or datetime.now()
comment Comment(emailleilaexample.com, contentfoo bar)声明一个序列化类使用它来序列化和反序列化与 Comment 对象相对应的数据 声明一个序列化类看起来非常类似于声明一个表单
from rest_framework import serializers
class CommentSerializer(serializers.Serializer):email serializers.EmailField()content serializers.CharField(max_length200)created serializers.DateTimeField()2、序列化对象
现在可以使用 CommentSerializer 来序列化评论或评论列表。同样使用 Serializer 类看起来很像使用 Form 类。
serializer CommentSerializer(comment)
serializer.data
# {email: leilaexample.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:leilaexample.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(datadata)
serializer.is_valid()
# True
serializer.validated_data
# {content: foo bar, email: leilaexample.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_length200)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(datadata)
# .save() will update the existing comment instance.
serializer CommentSerializer(comment, datadata).create() 和 .update() 方法都是可选的。您可以都不实现或者实现其中的一个或两个具体取决于你的序列化类的用例。
将附加属性传递给 .save()
有时你会希望你的视图代码能够在保存实例的时候注入额外的数据。这些附加数据可能包含当前用户当前时间或其他任何不属于请求数据的信息。
serializer.save(ownerrequest.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(fromemail, messagemessage)请注意在上面的情况下必须直接访问 serializer .validated_data 属性。
5、验证
在反序列化数据时你总是需要在尝试访问验证数据之前调用 is_valid()或者保存对象实例。如果发生任何验证错误那么 .errors 属性将包含一个代表错误消息的字典。例如
serializer CommentSerializer(data{email: foobar, content: baz})
serializer.is_valid()
# False
serializer.errors
# {email: [uEnter a valid e-mail address.], created: [uThis 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_exceptionTrue)字段级验证 你可以通过向 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_length100)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_length100)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(querysetEvent.objects.all(),fields[room_number, date])