@method_decorator 带有 login_required 和 permission_required

Posted

技术标签:

【中文标题】@method_decorator 带有 login_required 和 permission_required【英文标题】:@method_decorator with login_required and permission_required 【发布时间】:2015-06-22 18:58:28 【问题描述】:

我正在使用基于类的视图,我想确保每个视图都可以由登录用户和一种类型的用户访问(有两组用户 - 每个组都有不同的权限) .

我正在根据具有权限的文档(我使用的是 Django 1.7.7)https://docs.djangoproject.com/en/1.7/topics/class-based-views/intro/#decorating-the-class 来实现这一点,但是使用两个参数会引发错误“method_decorator() 只需要 1 个参数(给定 2 个) ”。

因此 - 如何在基于类的视图中验证这两个因素(登录和权限)?

class PatientCreate(CreateView):
    model = Patient
    fields = '__all__'

    @method_decorator(login_required, permission_required('patient.session.can_add_patient'))
    def dispatch(self, *args, **kwargs):
        return super(PatientCreate, self).dispatch(*args, **kwargs)

谢谢!

【问题讨论】:

【参考方案1】:

在您的情况下,permission_required 将重定向到未登录用户的登录页面,因此您根本不需要使用 login_required

@method_decorator(permission_required('patient.session.can_add_patient')
def dispatch(self, *args, **kwargs):
    ...

如果你确实需要使用多个装饰器,那么你可以在 Django 1.9+ 中使用列表

decorators = [other_decorator, permission_required('patient.session.can_add_patient')] 

class PatientCreate(CreateView):
    model = Patient
    fields = '__all__'

    @method_decorator(decorators)
    def dispatch(self, *args, **kwargs):
        ...

您还可以通过装饰类本身来缩短代码:

@method_decorator(decorators, name="dispatch")
class PatientCreate(CreateView):
    model = Patient
    fields = '__all__'

在 Django 1.8 及更早版本上,您无法将列表传递给 method_decorator 或装饰类,因此您必须堆叠装饰器

class PatientCreate(CreateView):
    model = Patient
    fields = '__all__'

    @method_decorator(other_decorator)
    @method_decorator(permission_required('patient.session.can_add_patient'))
    def dispatch(self, *args, **kwargs):
        ...

装饰器将按照传递给method_decorator 的顺序处理请求。所以对于上面的例子,other_decorator 将在permission_required 之前运行。

【讨论】:

好主意!谢谢! :) 顺便说一句 - 如何向重定向的用户显示我们没有该视图的权限? 您最好将其作为一个单独的问题提出。如果您使用raise_exception 参数(see docs),那么 Django 将返回 403 响应。您可以根据需要对其进行自定义(您可能必须处理未登录的用户)。 @BarthesSimpson 这最初是为 Django 1.7 编写的,当时您无法将列表传递给 method_decorator。我已经更新了 Django 1.9+ 的答案。

以上是关于@method_decorator 带有 login_required 和 permission_required的主要内容,如果未能解决你的问题,请参考以下文章

@method_decorator(csrf_exempt) NameError: name 'method_decorator' is not defined

django 基于类的视图是不是继承 method_decorators?

method_decorator的作用以及使用方法

Django中基于类的视图上带有参数的函数装饰器

云讲堂 | 5期视频带你全面了解滴滴Logi-KafkaManager

带有 DRF 的 cookie 的 Nuxt 身份验证