【问题标题】:django PermissionRequiredMixin permission_required not workingdjango PermissionRequiredMixin permission_required 不起作用
【发布时间】:2019-07-24 08:48:23
【问题描述】:

Views.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)

accounts/models.py

class User(AbstractBaseUser, PermissionsMixin):
    # some fields here
    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

        permissions = (
            ("template_all", "access to all templates"),
        )

视图名称.___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'>)

views.py 中的self.request.user.has_perms('accounts.template_all') 返回正确的布尔值,但是,self.has_permission() 每次都返回 True。 permission_required 没有效果,即使打印返回 false 用户仍然可以看到页面。 self.get_permission_required alos 返回正确的值。帮助表示赞赏。

【问题讨论】:

  • 我认为您应该以不同的方式订购基类:class viewName(PermissionRequiredMixin, AccessMixin, generic.TemplateView)。现在TemplateView 会覆盖您的PermissionRequiredMixin
  • 你的print(..) 测试没有将元组传递给has_perms,如果你这样称呼它会发生什么:print(self.request.user.has_perms('accounts.action_all',))

标签: python django permissions mixins user-permissions


【解决方案1】:

简而言之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 'django.views.generic.base.View'>, <class 'django.contrib.auth.mixins.PermissionRequiredMixin'>, <class 'django.contrib.auth.mixins.AccessMixin'>, <class 'object'>)

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

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

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

# PermissionRequiredMixin is put before TemplateView

class ViewName(PermissionRequiredMixin, TemplateView):
    permission_required = 'accounts.action_all'
    # ...

然后我们看到:

>>> ViewName.__mro__
(<class 'ViewName'>, <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'>)
>>> ViewName.dispatch
<function PermissionRequiredMixin.dispatch at 0x7f168b41d620>

【讨论】:

  • 感谢您的解释,我不知道,但是不幸的是,此更改并没有解决问题。
  • 另外,accessMixin应该在templateView之前吗?
  • @RudraMutalik:不,因为访问视图已经在PermissionRequiredView 中。 Django 使用self.request.user.has_perms(perms),这里有perms ('accounts.action_all',)(所以是一个元组),你确定它工作正常吗?
  • @RudraMutalik:我已经在本地进行了测试,它似乎可以工作。既然您自己指定了一个 User 模型,那么也许有些东西不完全正确?
  • self.request.user.has_perms('accounts.action_all') 返回正确的值,所以这似乎工作
猜你喜欢
  • 2015-05-29
  • 2017-02-11
  • 2011-03-27
  • 2022-01-02
  • 1970-01-01
  • 2014-02-10
  • 2016-04-30
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多