I am using Django REST Framework to serialize a Django model. I have a ListCreateAPIView view to list the objects and a RetrieveUpdateDestroyAPIView view to retrieve/update/delete individual objects. The model stores information that the users submit themselves. The information they submit contains some private information and some public information. I want all users to be able to list and retrieve the public information but I want only the owner to list/retrieve/update/delete the private information. Therefore, I need per-field permissions and not object permissions.
The closest suggestion I found was https://groups.google.com/forum/#!topic/django-rest-framework/FUd27n_k3U0 which changes the serializer based on the request type. This won't work for my situation because I don't have the queryset or object at that point to determine if it is owned by the user or not.
Of course, I have my frontend hiding the private information but smart people can still snoop the API requests to get the full objects. If code is needed, I can provide it but my request applies to vanilla Django REST Framework designs.
I figured out a way to do it. In the serializer, I have access to both the object and the user making the API request. I can therefore check if the requestor is the owner of the object and return the private information. If they are not, the serializer will return an empty string.
Here:
-- models.py:
-- serializers.py:
For a solution that allows both reading and writing, do this:
See the docs for an example.
In case you are performing only READ operations, you can just pop the fields in to_representation method of the serializer.
This should be enough to hide sensitive fields.
I had a similar problem the other day. Here is my approach:
This is a
DRF 2.4
solution.And a DRF 3.x solution:
This time we extend
ReadOnlyField
only becauseto_representation
is not implemented in theserializers.Field
class.How about switching serializer class based on user?
In documentation:
http://www.django-rest-framework.org/api-guide/generic-views/#get_serializer_classself