繁体   English   中英

Django Rest Framework 如何更新 SerializerMethodField

[英]Django Rest Framework How to update SerializerMethodField

我有一个这样的序列化程序:

class PersonSerializer(serializers.ModelSerializer):
    gender = serializers.SerializerMethodField()
    bio = BioSerializer()

    class Meta:
        model = Person
        fields = UserSerializer.Meta.fields + ('gender', 'bio',)

    def get_gender(self, obj):
        return obj.get_gender_display()

在执行 GET 请求时,我用它来显示“男”和“女”(插入“F”的“M”)。

这工作正常。

但是现在我正在为模型编写补丁方法,并且SerializerMethodField()具有read_only=True 所以我没有在serializer.validated_data()为性别字段传递值。 如何克服这个问题?

因此,如果我理解正确,您想在 PATCH 请求中发送 {'gender': 'Male'}。

因此,您必须告诉您的序列化程序如何将您的表示(即“男性”)转换为内部值。

正如您在 source看到的, SerializerMethodField 仅涵盖从内部值到表示的转换。

您可以实现一个自定义 SerializerField 来执行必要的转换。 一个天真的实现可能是这样的:

class GenderSerializerField(serializers.Field):

    VALUE_MAP = {
        'M': 'Male',
        'F': 'Female'
    }

    def to_representation(self, obj):
        return self.VALUE_MAP[obj]            

    def to_internal_value(self, data):
        return {k:v for v,k in self.VALUE_MAP.items()}[data]

class PersonSerializer(serializers.ModelSerializer):
    gender = GenderSerializerField()
    ...

请注意,这未经测试且缺乏任何验证,请查看自定义字段上DRF 文档

除了接受的答案之外,还可以有其他更简单的钩子。 如果“创建”和“更新”在修改gender字段之前按您的意愿工作,那么您可以按照以下步骤将所有内容设置为创建和更新请求的默认值。

  • 不要使用SerializerMethodField 而是覆盖序列化程序表示。
class PersonSerializer(serializers.ModelSerializer):
    bio = BioSerializer()
    
    class Meta:
        model = Person
        fields = UserSerializer.Meta.fields + ('bio',)


    def to_representation(self, obj):
        ret = super().to_representation(obj)
        ret['gender'] = obj.get_gender_display()
        return ret

  • 覆盖__init__方法。 .
class PersonSerializer(serializers.ModelSerializer):
    bio = BioSerializer()
    
     def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        try:
            if self.context['request'].method in ['GET']:
                self.fields['gender'] = serializers.SerializerMethodField()
        except KeyError:
            pass

    class Meta:
        model = Person
        fields = UserSerializer.Meta.fields + ('bio',)

    def get_gender(self, obj):
        return obj.get_gender_display()   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM