Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework: allow a serializer field to be created, but not edited

Right now, DRF's read_only argument on a Serializer constructor means you can neither create nor update the field, while the write_only argument on a Serializer constructor allows the field to be created OR updated, but prevents the field from being output when serializing the representation.

Is there any (elegant) way to have a Serializer field that can be created, exactly once, when the model in question is created (when the create() is called on the Serializer), but cannot that later be modified via update?

NB: Yes, I've seen this solution, but honestly I find it ugly and un-Pythonic. Is there a better way?

like image 555
ubadub Avatar asked Oct 28 '18 03:10

ubadub


2 Answers

class TodoModifySerializer(ModelSerializer):

    def to_internal_value(self, data):
        data = super(TodoModifySerializer, self).to_internal_value(data)
        if self.instance:
            # update
            for x in self.create_only_fields:
                data.pop(x)
        return data

    class Meta:
        model = Todo
        fields = ('id', 'category', 'title', 'content')
        create_only_fields = ('title',)

you can do it in to_internal_value method by remove this data when update

like image 54
Ykh Avatar answered Oct 25 '22 11:10

Ykh


By "not elegant", I'm assuming you only want one serializer for both creates and updates. You could perhaps consider overriding the update method of your serializer and remove the create_only_field from validated_data before saving:

class MySerializer(serializers.ModelSerializer):

    def update(self, instance, validated_data):
        validated_data.pop('create_only_field')
        return super().update(instance, validated_data)

    class Meta:
        model = MyModel
        fields = ('id', 'field_one', 'field_two', 'create_only_field')

You would, however, have to supply the old (or some) field value when updating your model.

like image 28
slider Avatar answered Oct 25 '22 10:10

slider