I am writing a Serializer for my model which will be accessed using GET, POST and PATCH endpoints. I have a property in my model which I am using as a source for a field. However, using source=
in serializer field is making it ready-only.
If I remove the source="get_field1"
from the
field1 = serializers.NullBooleanField(source="get_field1")
then I am able to update the data.
But I HAVE to use the source to get the right value of the field.
class MyModel(models.Model):
field1 = NullBooleanField(default=None)
@property
get_field1(self):
data = True
# ...some logic
return data
Now I have a serializer that I am using
class MyModelSerializer(serializers.ModelSerializer):
field1 = serializers.NullBooleanField(source="get_field1")
class Meta:
model = MyModel
fields = ('field1')
Now in my API endpoint, I do this
serializer = MyModelSerializer(my_model, data=request.data, partial=True)
if serializer.is_valid():
serializer.save() # <- throws error "can't set attribute"
Also, I would like to mention that the field in the serializer is referred by the property name and not by the field name.
Example: If I do
>> serializer.validated_data
>> 'OrderedDict(['get_field1'], True) # <- shouldn't this by field1 and not get_field1
Answer by @JPG is good, but I feel it's a hacky way.
I would override the to_representation
method of the Serializer to achieve your purpose.
Here's what you can do
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')
This way you are implicitly providing the source and your field becomes writeable. So every time you GET, POST, or PATCH you'll get the right value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With