@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?