Skip to main content
 首页 » 编程设计

python之django PermissionRequiredMixin permission_required 不工作

2024年08月14日42jpfss

View .py

class templateList(PermissionRequiredMixin, TemplateView): 
    permission_required = 'accounts.template_all' 
 
    def get(self, request, *args, **kwargs): 
        #view logic 
        print(self.request.user.has_perms('accounts.template_all')) 
        return render(request, template_name, context) 

账户/模型.py

class User(AbstractBaseUser, PermissionsMixin): 
    # some fields here 
    class Meta: 
        verbose_name = _('user') 
        verbose_name_plural = _('users') 
 
        permissions = ( 
            ("template_all", "access to all templates"), 
        ) 

ViewName.___mro____

(<class 'template.views.templateList'>, <class 'django.contrib.auth.mixins.PermissionRequiredMixin'>, <class 'django.contrib.auth.mixins.AccessMixin'>, <class 'django.views.generic.base.TemplateView'>, <class 'django.views.generic.base.TemplateResponseMixin'>, <class 'django.views.generic.base.ContextMixin'>, <class 'django.views.generic.base.View'>, <class 'object'>) 

self.request.user.has_perms('accounts.template_all') 在 vi​​ews.py 中返回正确的 bool 值,但是,self.has_permission() 返回 True每次。 permission_required 无效,即使打印返回 false,用户仍然可以看到该页面。 self.get_permission_required 也返回正确的值。感谢帮助。

请您参考如下方法:

简而言之:PermissionRequiredMixin 基类应该放在 TemplateView 基类之前,这样 MRO (方法解析顺序)是正确的,并且调度指向 PermissionRequiredMixin 的重写。

一个 PermissionRequiredMixin 修补了 dispatch(..) 方法(好吧,它添加了一个额外的检查,看看用户是否有适当的权限)。然而,在这里您将子类按顺序放置,导致 dispatch(..) 函数是来自 View 类的函数。

确实,如果我们看一下 MRO,我们会看到:

>>> ViewName.__mro__ 
(<class 'ViewName'>, <class 'django.views.generic.base.TemplateView'>, <class 'django.views.generic.base.TemplateResponseMixin'>, <class 'django.views.generic.base.ContextMixin'>, <class <b>'django.views.generic.base.View'</b>>, <class <b>'django.contrib.auth.mixins.PermissionRequiredMixin'</b>>, <class 'django.contrib.auth.mixins.AccessMixin'>, <class 'object'>)

如果我们看一下调用 .dispatch(..) 时调用的方法,我们会看到:

>>> ViewName.dispatch 
<function View.dispatch at 0x7f169e8f6620> 

为了让mixin覆盖原来的.dispatch(..)函数,我们需要把它放在基类的最前面,比如:

# PermissionRequiredMixin is put <i>before</i> TemplateView 
 
class ViewName(<b>PermissionRequiredMixin, TemplateView</b>): 
    permission_required = 'accounts.action_all' 
    # ...

然后我们看到:

>>> ViewName.__mro__ 
(<class 'ViewName'>, <class <b>'django.contrib.auth.mixins.PermissionRequiredMixin'</b>>, <class 'django.contrib.auth.mixins.AccessMixin'>, <class 'django.views.generic.base.TemplateView'>, <class 'django.views.generic.base.TemplateResponseMixin'>, <class 'django.views.generic.base.ContextMixin'>, <class <b>'django.views.generic.base.View'</b>>, <class 'object'>) 
>>> ViewName.dispatch 
<function <b>PermissionRequiredMixin.dispatch</b> at 0x7f168b41d620>