python - django PermissionRequiredMixin permission_required 不起作用
问题描述
视图.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')
在 views.py 中返回正确的布尔值,但是self.has_permission()
每次都返回 True。permission_required
没有效果,即使打印返回 false,用户仍然可以看到页面。self.get_permission_required
alos 返回正确的值。帮助表示赞赏。
解决方案
简而言之:PermissionRequiredMixin
基类应该放在基类之前,TemplateView
这样 MRO(方法解析顺序)是正确的,并且调度指向PermissionRequiredMixin
.
APermissionRequiredMixin
修补该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>
推荐阅读
- ios - 'FIRMessaging' 没有可见的@interface 声明选择器'sendMessage:to:withMessageID:timeToLive:'
- spring-boot - Spring Boot 应用程序中的 com.codahale.metrics.Gauges
- python - 如何在 PySimpleGui 中设置两个可互换的可见容器?
- graph - Torch Tensorboard 图不反映代码
- terraform - Terraform - 从模块创建输出,但 splat 运算符不起作用
- holoviews - Datashader:GeoDataFrames 的分类颜色映射
- c++ - 无法为 .c 文件创建静态库。获取 src/crc16.c:35:10: 致命错误: defs.h: No such file or directory 错误
- scala - Scala 中的嵌套过滤器要么在 Future[Try[Int]] 之上
- android - iOS Motion vs Android Sensor 四元数数据
- typescript - 如何在 TypeScript 中声明由 for await 动态创建的对象的类型