Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Per Field Permission in Django REST Framework

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.

like image 528
ravishi Avatar asked Oct 02 '13 01:10

ravishi


People also ask

What is permission in Django REST framework?

Permissions are used to grant or deny access for different classes of users to different parts of the API. The simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds to the IsAuthenticated class in REST framework.

What is write only field Django REST framework?

From DRF v3 onwards, setting a field as read-only or write-only can use serializer field core arguments mentioned as follows. write_only. Set this to True to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.

Which authentication is best in Django REST framework?

JSON Web Token Authentication Unlike the built-in TokenAuthentication scheme, JWT Authentication doesn't need to use a database to validate a token. A package for JWT authentication is djangorestframework-simplejwt which provides some features as well as a pluggable token blacklist app.


2 Answers

How about switching serializer class based on user?

In documentation:

http://www.django-rest-framework.org/api-guide/generic-views/#get_serializer_classself

def get_serializer_class(self):     if self.request.user.is_staff:         return FullAccountSerializer     return BasicAccountSerializer 
like image 151
jho Avatar answered Sep 19 '22 01:09

jho


I had a similar problem the other day. Here is my approach:

This is a DRF 2.4 solution.

class PrivateField(serializers.Field):     def field_to_native(self, obj, field_name):         """         Return null value if request has no access to that field         """         if obj.created_by == self.context.get('request').user:             return super(PrivateField, self).field_to_native(obj, field_name)         return None  #Usage class UserInfoSerializer(serializers.ModelSerializer):     private_field1 = PrivateField()     private_field2 = PrivateField()      class Meta:         model = UserInfo 

And a DRF 3.x solution:

class PrivateField(serializers.ReadOnlyField):      def get_attribute(self, instance):         """         Given the *outgoing* object instance, return the primitive value         that should be used for this field.         """         if instance.created_by == self.context['request'].user:             return super(PrivateField, self).get_attribute(instance)         return None 

This time we extend ReadOnlyField only because to_representation is not implemented in the serializers.Field class.

like image 23
Todor Avatar answered Sep 23 '22 01:09

Todor