[英]Django Rest Framework How to update SerializerMethodField
I have a serializer like this:我有一个这样的序列化程序:
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()
I used this to display "Male" and "Female"(insted of "M" of "F") while performing GET request.在执行 GET 请求时,我用它来显示“男”和“女”(插入“F”的“M”)。
This works fine.这工作正常。
But now I am writing an patch method for the model and SerializerMethodField()
has read_only=True
.但是现在我正在为模型编写补丁方法,并且SerializerMethodField()
具有read_only=True
。 So I am not getting value passed for gender field in serializer.validated_data()
.所以我没有在serializer.validated_data()
为性别字段传递值。 How to overcome this issue?如何克服这个问题?
So if I understand you correctly, you want to send {'gender': 'Male'} in your PATCH request.因此,如果我理解正确,您想在 PATCH 请求中发送 {'gender': 'Male'}。
Therefor, you have to tell your serializer how to convert your representation ie 'Male' into the internal value.因此,您必须告诉您的序列化程序如何将您的表示(即“男性”)转换为内部值。
As you can see in source , SerializerMethodField only covers the conversion from internal value to the representation.正如您在 source中看到的, SerializerMethodField 仅涵盖从内部值到表示的转换。
You can implement a custom SerializerField that performs the necessary conversions.您可以实现一个自定义 SerializerField 来执行必要的转换。 A naive implementation could something like this:一个天真的实现可能是这样的:
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()
...
Note that this untested and lacks any validation, check out the DRF docs on custom fields .请注意,这未经测试且缺乏任何验证,请查看自定义字段上的DRF 文档。
Aside from accepted answer, there can be other simpler hooks.除了接受的答案之外,还可以有其他更简单的钩子。 If 'create' and 'update' worked as you wanted before modifiying gender
field, then you can do as follow to get everything to default for create and update requests.如果“创建”和“更新”在修改gender
字段之前按您的意愿工作,那么您可以按照以下步骤将所有内容设置为创建和更新请求的默认值。
SerializerMethodField
.不要使用SerializerMethodField
。 Instead override serializer representation.而是覆盖序列化程序表示。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__
method .覆盖__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.