class MyModelSerializer(serializer.ModelSerializer):
# 与model中字段一样(不需要转化)
title = serializer.CharField(max_length=10, require=True)
# user是外键 (需要序列化输出为作者名字)
author = Serializer.CharField(source='user.name')
# 方法二
author = Serializer.SerializerMethodField()
# 自定义函数 格式为get_xxx()
def get_author(self, instance):
return instance.user.name
# 定义序列化的数据(序列化的字段,验证,指定模型)
class Meta:
model = Articlemodel
field = ('id', 'title', 'author')
extra_kwargs = {
"project_number": {
"required": True,
"allow_null":True,
"allow_blank": True
}
Serializer类中函数
def to_internal_value(self, data):
# 反序列化前对数据进行操作
pass
def to_representation(self, instance):
# 序列化前对数据进行操作
pass
字段级别验证 (Field-level validation)
您可以通过向您的 Serializer
子类中添加 .validate_<field_name>
方法来指定自定义字段级的验证。这些类似于 Django 表单中的 .clean_<field_name>
方法。这些方法采用单个参数,即需要验证的字段值。
您的 validate_<field_name>
方法应该返回已验证的值或抛出 serializers.ValidationError
异常。例如:
from rest_framework import serializers
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
def validate_title(self, value):
"""
Check that the article is about Django.
"""
if 'django' not in value.lower():
raise serializers.ValidationError("Article is not about Django")
return value
注意:如果在您的序列化器上声明了 <field_name>
的参数为 required=False
,那么如果不包含该字段,则此验证步骤不会发生。
对象级别验证 (Object-level validation)
要执行需要访问多个字段的任何其他验证,请添加名为 .validate()
的方法到您的 Serializer
子类中。此方法采用单个参数,该参数是字段值的字典。如果需要,它应该抛出 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
验证器 (Validators)
序列化器上的各个字段都可以包含验证器,通过在字段实例上声明,例如:
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])
...
DRF还提供了很多可重用的验证器,比如UniqueValidator,UniqueTogetherValidator等等。通过在内部 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']
)
重写序列化器的create和update方法
假设我们有个Profile模型与User模型是一对一的关系,当用户注册时我们希望把用户提交的数据分别存入User和Profile模型,这时我们就不得不重写序列化器自带的create方法了。下例演示了如何通过一个序列化器创建两个模型对象。
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ('username', 'email', 'profile')
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(user=user, **profile_data)
return user
同时更新两个关联模型实例时也同样需要重写update方法。
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile')
# 除非应用程序正确地强制始终设置该字段,否则就应该抛出一个需要处理的`DoesNotExist`。
profile = instance.profile
instance.username = validated_data.get('username', instance.username)
instance.email = validated_data.get('email', instance.email)
instance.save()
profile.is_premium_member = profile_data.get(
'is_premium_member',
profile.is_premium_member
)
profile.has_support_contract = profile_data.get(
'has_support_contract',
profile.has_support_contract
)
profile.save()
return instance
因为序列化器使用嵌套后,创建和更新的行为可能不明确,并且可能需要相关模型之间的复杂依赖关系,REST framework 3 要求你始终显式的编写这些方法。默认的 ModelSerializer
.create()
和 .update()
方法不包括对可写嵌套表示的支持,所以我们总是需要对create和update方法进行重写。