28👍
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.
72👍
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 afterhas_permission
method returns valueTrue
except in POST method (inPOST
method onlyhas_permission
is executed).- When a
False
value is returned from thepermission_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 onHTTP POST
request, hence we need to restrict it fromhas_permission
method.
- [Django]-How to pass django rest framework response to html?
- [Django]-Detect whether Celery is Available/Running
- [Django]-Altering one query parameter in a url (Django)
3👍
has_permission()
is a method on the BasePermission class that is used to check if the user has permission to perform a certain action on the entire model. For example, you might use it to check if a user has permission to view a list of all objects of a certain model.
has_object_permission()
is a method on the BasePermission class that is used to check if the user has permission to perform a certain action on a specific instance of the model. For example, you might use it to check if a user has permission to view, update or delete a specific object of a certain model.
For example, you might have a Book model and a User model in your application. You could use has_permission()
to check if a user has permission to view a list of all books, while you use has_object_permission()
to check if a user has permission to view, update or delete a specific book.
class IsBookOwnerOrAdmin(permissions.BasePermission):
def has_permission(self, request, view):
# Check if the user is authenticated
if not request.user.is_authenticated:
return False
# Allow access for superusers
if request.user.is_superuser:
return True
# Allow access if the user is the owner of the book
if request.method in permissions.SAFE_METHODS:
return True
return False
def has_object_permission(self, request, view, obj):
# Allow access for superusers
if request.user.is_superuser:
return True
# Allow access if the user is the owner of the book
return obj.owner == request.user
- [Django]-Django The 'image' attribute has no file associated with it
- [Django]-Override existing Django Template Tags
- [Django]-Django-way for building a "News Feed" / "Status update" / "Activity Stream"
1👍
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
- [Django]-Easily rename Django project
- [Django]-Uwsgi installation error in windows 7
- [Django]-How do I force Django to ignore any caches and reload data?
0👍
As far as I can see, you are not adding your custom permission to the class as an argument.
This is your code:
class StudentUpdateAPIView(RetrieveUpdateAPIView):
serializer_class = StudentCreateUpdateSerializer
queryset = Student.objects.all()
lookup_field = 'pk'
permissions_classes = [IsAuthenticatedAndOwner]
But it should be:
class StudentUpdateAPIView(RetrieveUpdateAPIView, IsAuthenticatedAndOwner):
serializer_class = StudentCreateUpdateSerializer
queryset = Student.objects.all()
lookup_field = 'pk'
permissions_classes = [IsAuthenticatedAndOwner]
Note the custom permission IsAuthenticatedAndOwner
as an argument in the class header.
PS: I hope this helps, I am a beginner in DRF but this is one of the things I just learned.
- [Django]-'NOT NULL constraint failed' after adding to models.py
- [Django]-How do I use Django templates without the rest of Django?
- [Django]-How do I perform HTML decoding/encoding using Python/Django?