序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSON,XML 或其他内容类型。序列化器还提供反序列化,在首次验证传入数据之后,可以将解析的数据转换回复杂类型。
REST framework 中的序列化类与 Django 的 Form 和 ModelForm 类非常相似。我们提供了一个 Serializer 类,它提供了一种强大的通用方法来控制响应的输出,以及一个 ModelSerializer 类,它为创建处理模型实例和查询集的序列化提供了有效的快捷方式。
serializers.Serializer
举个小栗子
# app/serializers.py from rest_framework import serializers from datetime import datetime class DemoSerializer(serializers.Serializer): email = serializers.EmailField() content = serializers.CharField(max_length=200) created = serializers.DateTimeField() # app/views.py class DemoAPIView(APIView): def get(self, request, *args, **kwargs): comment = { "email":"leila@example.com", "content":"foo bar", "created":datetime.now() } serializer = DemoSerializer(data=comment) serializer.is_valid(raise_exception=True) data = serializer.validated_data return Response(data=data)
.is_valid() 方法带有一个可选的 raise_exception 标志,如果存在验证错误,将导致它引发 serializers.ValidationError 异常。
保存实例
BaseSerializer save源码
def save(self, **kwargs): ... validated_data = dict( list(self.validated_data.items()) + list(kwargs.items()) ) if self.instance is not None: self.instance = self.update(self.instance, validated_data) assert self.instance is not None, ( '`update()` did not return an object instance.' ) else: self.instance = self.create(validated_data) assert self.instance is not None, ( '`create()` did not return an object instance.' ) return self.instance
调用自身create,update方法。
字段验证
你可以通过向 Serializer 子类添加 .validate_<field_name> 方法来指定自定义字段级验证。这些与 Django 表单上的 .clean_<field_name> 方法类似。
这些方法只有一个参数,就是需要验证的字段值。
您的 validate_<field_name> 方法应返回验证值或引发 serializers.ValidationError。
for example
# app/serializers.py import re from datetime import datetime from rest_framework import serializers class DemoSerializer(serializers.Serializer): email = serializers.EmailField() mobile = serializers.CharField(max_length=11) content = serializers.CharField(max_length=200) created = serializers.DateTimeField() def validate_mobile(self, value): condition = re.search(r"1[34578][0-9]{9}", value) if condition: return value else: raise serializers.ValidationError( "请输入合法的手机号" ) # app/views.py class DemoAPIView(APIView): def get(self, request, *args, **kwargs): comment = { "email":"leila@example.com", "mobile":"12354521541", "content":"foo bar", "created":datetime.now() } serializer = DemoSerializer(data=comment) serializer.is_valid(raise_exception=True) data = serializer.validated_data return Response(data=data)
对象级验证
如果要对多个字段进行其他的验证,请将一个名为 .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
处理嵌套对象
前面的例子适用于处理只具有简单数据类型的对象,但有时还需要能够表示更复杂的对象,其中对象的某些属性可能不是简单的数据类型,如字符串,日期或整数。
Serializer 类本身就是一种 Field,可以用来表示一个对象类型嵌套在另一个对象类型中的关系。
class UserSerializer(serializers.Serializer): email = serializers.EmailField() username = serializers.CharField(max_length=100) class CommentSerializer(serializers.Serializer): user = UserSerializer() content = serializers.CharField(max_length=200) created = serializers.DateTimeField()
如果嵌套对象可以是 None 值,则应将 required = False 标志传递给嵌套的序列化类。
class CommentSerializer(serializers.Serializer): user = UserSerializer(required=False) # May be an anonymous user. content = serializers.CharField(max_length=200) created = serializers.DateTimeField()
同样,如果嵌套对象是一个列表,则应将 many = True 标志传递给嵌套的序列化类。
class CommentSerializer(serializers.Serializer): user = UserSerializer(required=False) edits = EditItemSerializer(many=True) # A nested list of 'edit' items. content = serializers.CharField(max_length=200) created = serializers.DateTimeField()
ModelSerializer
通常你会想要序列化类紧密地映射到 Django 模型定义上。
ModelSerializer 类提供了一个快捷方式,可让你自动创建一个 Serializer 类,其中的字段与模型类字段对应。
ModelSerializer 类与常规 Serializer 类相同,不同之处在于:
它会根据模型自动生成一组字段。
它会自动为序列化类生成验证器,例如 unique_together 验证器。
它包含 .create() 和 .update() 的简单默认实现。
声明ModelSerializer如下所示:
class AccountSerializer(serializers.ModelSerializer): class Meta: model = Account fields = ('id', 'account_name', 'users', 'created')
class AccountSerializer(serializers.ModelSerializer): class Meta: model = Account fields = "__all__"
class AccountSerializer(serializers.ModelSerializer): class Meta: model = Account exclude = ('users',)