我正在为我的模型编写一个序列化器,可以使用GET,POST和PATCH端点进行访问。我的模型中有一个属性,我将其用作字段的源。但是,在序列化程序字段中使用source=
使其仅准备就绪。
如果我从
删除source="get_field1"
field1 = serializers.NullBooleanField(source="get_field1")
然后我就可以更新数据。
但是我必须使用源来获取字段的正确值。
class MyModel(models.Model):
field1 = NullBooleanField(default=None)
@property
get_field1(self):
data = True
# ...some logic
return data
现在我有一个正在使用的序列化器
class MyModelSerializer(serializers.ModelSerializer):
field1 = serializers.NullBooleanField(source="get_field1")
class Meta:
model = MyModel
fields = ('field1')
现在在我的API端点中,我这样做
serializer = MyModelSerializer(my_model, data=request.data, partial=True)
if serializer.is_valid():
serializer.save() # <- throws error "can't set attribute"
此外,我还要提到序列化程序中的字段是由属性名称而不是字段名称引用的。
示例:如果我这样做
>> serializer.validated_data
>> 'OrderedDict(['get_field1'], True) # <- shouldn't this by field1 and not get_field1
答案 0 :(得分:3)
这可以通过覆盖序列化程序的 __init__()
方法来完成。除此之外,我们还需要将一些 context
数据传递给序列化程序,以区分GET
,POST
和{ {1}}个请求。
PATCH
并且在序列化数据时,不要忘记将请求作为上下文传递,就像
class MyModelSerializer(serializers.ModelSerializer):
field1 = serializers.NullBooleanField() # remove "source" argument from here
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.context['request'].method == 'GET':
self.fields['field1'] =serializers.NullBooleanField(source= "get_field1")
class Meta:
model = MyModel
fields = ('field1',)
答案 1 :(得分:2)
@JPG的回答很好,但是我觉得这是一种怪诞的方式。
我将重写Serializer的to_representation
方法以实现您的目的。
这就是你可以做的
class MyModelSerializer(serializers.ModelSerializer):
field1 = serializers.NullBooleanField() # get rid of source
def to_representation(self, instance):
data = super(MyModel, self).to_representation(instance)
data.update({
'field1': instance.get_field1
})
return data
class Meta:
model = MyModel
fields = ('field1')
这样,您将隐式提供源,并且您的字段可写。因此,每次执行GET,POST或PATCH时,您都会获得正确的值。