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.
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.
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.
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.
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
I had a similar problem the other day. Here is my approach:
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With