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

?

+9


source to share


3 answers


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.

+10


source


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 the has_permission

    method returns a value True

    , except for the POST method (in the POST method has_permission

    only gets executed).
  • When the value is False

    returned from the method permission_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

+9


source


permission_classes

not permissions_classes

I'm stupid.

0


source







All Articles