What's the differences between has_object_permission and has_permission in DRF:Permission?

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 Django DRF method def get_object(self). Hence, has_object_permission method is available 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 has_permission only be executed).
  • When 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.

Basically, the first code denies everything because has_permission return False.

has_permission is a check made before calling the has_object_permission. That means that you need to be allowed by has_permission before you get any chance to check the ownership test.

What you want is:

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

This will also allow authenticated users to create new items or list them.


I think this can help:

class IsAuthorOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        # Read-only permissions are allowed for any request
        if request.method in permissions.SAFE_METHODS:
            return True
        # Write permissions are only allowed to the author of a post
        return obj.user == request.user