What are the differences between has_object_permission and has_permission in DRF: permission?
I am confused with BasePermission
the 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
Use 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. Anyone can transfer permission and update data.
called
was not 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 function
class UserCreateAPIView(CreateAPIView):
serializer_class = UserCreateSerializer
queryset = User.objects.all()
permission_classes = [IsNotAuthenticated]
So what are the differences between the above examples and the has_object_permission
& function has_permission
?
source to share
Essentially, the first code negates everything because it has_permission
returns False.
has_permission
- the check performed before the call has_object_permission
. This means that you has_permission
must give you permission before you can verify ownership.
What you want is this:
class IsAuthenticatedAndOwner(BasePermission):
message = 'You must be the owner of this object.'
def has_permission(self, request, view):
return request.user and request.user.is_authenticated
def has_object_permission(self, request, view, obj):
return obj.user == request.user
It will also allow authenticated users to create new items or list them.
source to share
We have two permission methods for the BasePermission class:
- def has_permission (self, request, view)
- def has_object_permission (self, request, view, obj)
These two different methods are called to restrict unauthorized users from inserting and manipulating data.
has_permission
is called for all HTTP requests, whereas it has_object_permission
is called from Django's DRF method def get_object(self)
. Therefore, has_object_permission
a method is available GET
, PUT
, DELETE
, not POST
a request.
Eventually:
permission_classes
loops on a specific list.has_object_permission
the method is called after thehas_permission
method returns a valueTrue
, except for the POST method (in the POST methodhas_permission
only gets executed).- When the value is
False
returned from the methodpermission_classes
, the request is not granted permission and will no longer loop, otherwise it checks all loop permissions. has_permission
method will be called for all (GET
,POST
,PUT
,DELETE
)HTTP
request.has_object_permission
the method will not be called on demand , so we must restrict its use of the method .HTTP
POST
has_permission
source to share