Discussion:
How to invalidate/refresh serializer._writable_fields?
e***@eventcloud.co
2018-06-25 12:47:16 UTC
Permalink
I have a mixin which sets a few fields as read-only but only for some
specific actions, printing out extra_kwargs shows the mixin is intercepting
and changing these correctly for the serializer instance when the
appropriate action is performed yet the read_only nature is not being
enforced at all.


How can I invalidate/refresh serializer._writable_fields so I can do that
before I call serializer.save()


Usage of multiple serializers has been suggested but this would not be the
solution we would want as that would result in an explosion on the number
of serializers we have so we would instead prefer to go with intelligent
serializers via mixins.


Example mixin code for update action:

class ReadOnlyOnUpdateFieldsSerializerMixin(serializers.Serializer):
def get_extra_kwargs(self):
extra_kwargs = super().get_extra_kwargs()
# Intercept on update.
if 'update' in getattr(self.context.get('view'), 'action', ''):
return self._set_update_read_only_fields(extra_kwargs)

return extra_kwargs

def _set_update_read_only_fields(self, extra_kwargs):
"""Set all fields in `Meta.update_read_only_fields` to read_only."""
update_read_only_fields = getattr(self.Meta, 'update_read_only_fields', None)
if not update_read_only_fields:
return extra_kwargs

if not isinstance(update_read_only_fields, (list, tuple)):
raise TypeError('The `update_read_only_fields` option must be either a list or tuple. '
'Got {}.'.format(type(update_read_only_fields).__name__))

for field_name in update_read_only_fields:
kwargs = extra_kwargs.get(field_name, {})
kwargs['read_only'] = True
extra_kwargs[field_name] = kwargs
#log.info(extra_kwargs)
return extra_kwargs



To get around this issue we currently have this as part of the mixin as
well now:

def update(self, instance, validated_data):
for i in self.Meta.update_read_only_fields:
if i in validated_data:
validated_data.pop(i)
return super().update(instance, validated_data)



I would like to know how to get the serializer to ignore these special
fields based on the updated extra_kwargs though or if this is indeed
possible at all, the concept of write-once fields comes up so often for us
it would be nice if there was a proper way built into drf for this.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...