I am confused with the BasePermission
in Django-rest-framework.
Here I defined a class: IsAuthenticatedAndOwner
.
class IsAuthenticatedAndOwner(BasePermission): message = 'You must be the owner of this object.' def has_permission(self, request, view): print('called') return False def has_object_permission(self, request, view, obj): # return obj.user == request.user return False
Using in views.py
class StudentUpdateAPIView(RetrieveUpdateAPIView): serializer_class = StudentCreateUpdateSerializer queryset = Student.objects.all() lookup_field = 'pk' permissions_classes = [IsAuthenticatedAndOwner]
But it doesn't work at all. Everyone can pass the permission and update the data.
The called
wasn't printed.
And I used to define this class: IsNotAuthenticated
class IsNotAuthenticated(BasePermission): message = 'You are already logged in.' def has_permission(self, request, view): return not request.user.is_authenticated()
It works well in the function
class UserCreateAPIView(CreateAPIView): serializer_class = UserCreateSerializer queryset = User.objects.all() permission_classes = [IsNotAuthenticated]
So, what are the differences between the examples above, and function has_object_permission
& has_permission
?
has_permission vs has_object_permission If access is refused, the objects never get retrieved. Detail views, has_permission is executed and then only if permission is granted, has_object_permission is executed after the object is retrieved.
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.
We have following two permission methods on BasePermission
class:
def has_permission(self, request, view)
def has_object_permission(self, request, view, obj)
Those two different methods are called for restricting unauthorized users for data insertion and manipulation.
has_permission
is called on all HTTP requests whereas, has_object_permission
is called from DRF's method def get_object(self)
. Hence, has_object_permission
method is available for GET
, PUT
, DELETE
, not for POST
request.
In summary:
permission_classes
are looped over the defined list.has_object_permission
method is called after has_permission
method returns value True
except in POST method (in POST
method only has_permission
is executed).False
value is returned from the permission_classes
method, the request gets no permission and will not loop more, otherwise, it checks all permissions on looping.has_permission
method will be called on all (GET
, POST
, PUT
, DELETE
) HTTP
request.has_object_permission
method will not be called on HTTP POST
request, hence we need to restrict it from has_permission
method.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