I am using Django Guardian
to have object-level permission along with global permissions. Some of the users have a group with global permissions, and some have object-level permissions. With this, I seem to need to modify the PermissionRequiredMixin
to check also for the object-level permission.
views.py
class MainPageView(PermissionRequiredMixin, TemplateView):
permission_required = "app.view_mainpage"
template_name = "web/mainpage.html"
This one works if the user has global permission but if the user is under a group with object-level permission, it won't. With guardian, to check for object-level permission, you also have to pass the object instance.
example:
self.request.user.has_perm('view_mainpage', obj)
And on PermissionRequiredMixin
, the checking goes only like this, self.request.user.has_perms(perms)
So if the user has a group with permission of view_mainpage
of a specific object, how can I check it too? By the way, all my permissions are of the same content_type
. Is there any way I can execute this? Like I have to pass the object instance to PermissionRequiredMixin
if the user is under an object-level group and None
if the user is under a global group.
You can implement such mixin yourself with:
from django.core.exceptions import PermissionDenied
class ObjectPermissionRequiredMixin:
object_permission_required = None
object_permission_denied_message = None
def has_object_permission(self, obj):
return self.request.user.has_perm(self.object_permission_required, obj)
def get_object_permission_denied_message(self):
return self.object_permission_denied_message
def handle_no_object_permission(self):
raise PermissionDenied(self.get_object_permission_denied_message())
def get_object(self, *args, **kwargs):
obj = super().get_object(*args, **kwargs)
if not self.has_object_permission(obj)
return self.handle_no_object_permission()
return obj
Then you can mix this mixin into a view, for example:
class MyUpdateView(ObjectPermissionRequiredMixin, UpdateView):
model = MyModel
object_permission_required = 'app.update_my_model'
object_permission_denied_message = 'You can not edit this object'
This will work for all View
s that usee the SingleObjectMixin
[Django-doc] such as a DetailView
, UpdateView
, and the DeleteView
.