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 serializersclass 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 serializersclass 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 = Userfields = ('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.profileinstance.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方法进行重写。
742

被折叠的 条评论
为什么被折叠?



