DRF序列化与反序列化

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方法进行重写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值