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