0
votes

I have a serializer that accepts two objects, one of which is always constant once a user has authenticated.

The serializer, of course, should not need to know these details; it should know only that it serializes and deserializes an object with two fields.

Further, the user, having authenticated, should only have to pass in the value he wishes to set to the non-constant field via the viewset.

So what I need is a hook somewhere that intercepts the data before the serializer receives it, sets the constant field to the user's set value, and then allows processing to proceed as usual.

Is there any such hook in DRF? The solutions I've seen are all very hacky: context (coupling of view and serialization logic); validations (more coupling); and so forth. In theory what we want is:

data = union(userFields, fixedFieldsForView)
Serializer(data=data)

where the data part is somehow handled in the view only. Note also this is only during creation and update of objects, not reads (which are filtered already by get_queryset).

2

2 Answers

1
votes

If the question is about adding additional parameters to the serializer, then yes:

  • save the sterilizer with the extra arguments serializer.save(extra_arg=value, extra_arg2=value)
  • override the view's perform_create and perform_update to call the serializer.save
1
votes

We took the following approach. Feedback welcome.

def get_serializer(self, *args, **kwargs):
    if self.request.method == 'POST' and 'data' in kwargs:
        kwargs['data']['fixed_value'] = self.get_user_fixed_value()
    return super(OurModel, self).get_serializer(*args, **kwargs)

So when a user POSTs to the endpoint, regardless the setting of fixed_value, that value will always be set correctly.

Still feels like a bit of a hack, but works for us for now.