Make PermissionRequiredMixin 还检查对象级权限

Make PermissionRequiredMixin also check for object level permission

我正在使用 Django Guardian 来获得对象级权限和全局权限。一些用户拥有一个具有全局权限的组,一些拥有对象级权限。有了这个,我似乎需要修改 PermissionRequiredMixin 以检查对象级权限。

views.py

class MainPageView(PermissionRequiredMixin, TemplateView):
    permission_required = "app.view_mainpage"
    template_name = "web/mainpage.html"

如果用户具有全局权限,则此方法有效,但如果用户在具有对象级权限的组中,则无效。使用监护人,要检查对象级别的权限,您还必须传递对象实例。

示例:

self.request.user.has_perm('view_mainpage', obj)

而在 PermissionRequiredMixin 上,检查只是这样进行的,self.request.user.has_perms(perms)

那么,如果用户拥有一个具有特定对象 view_mainpage 权限的组,我该如何检查呢?顺便说一句,我所有的权限都是一样的content_type。有什么办法可以执行吗?如果用户在对象级组下,我必须将对象实例传递给 PermissionRequiredMixin,如果用户在全局组下,我必须将对象实例传递给 None

您可以自己实现这样的混合:

from django.core.exceptions import <strong>PermissionDenied</strong>

class ObjectPermissionRequiredMixin:
    object_permission_required = None
    object_permission_denied_message = None

    def <strong>has_object_permission</strong>(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 <strong>self.has_object_permission(obj)</strong>
            return self.handle_no_object_permission()
        return obj

然后你可以将这个mixin混合到一个视图中,例如:

class MyUpdateView(<strong>ObjectPermissionRequiredMixin,</strong> UpdateView):
    model = MyModel
    <strong>object_permission_required = 'app.update_my_model'</strong>
    <strong>object_permission_denied_message = 'You can not edit this object'</strong>

这将适用于所有使用 SingleObjectMixin [Django-doc]View,例如 DetailViewUpdateViewDeleteView