我正在尝试实现 Staff_member_required mixin:
以下是我发现的两种方法:
第一:
class StaffRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
if not request.user.is_staff:
messages.error(
request,
'You do not have the permission required to perform the '
'requested operation.')
return redirect(settings.LOGIN_URL)
return super(StaffRequiredMixin, self).dispatch(request,
*args, **kwargs)
第二:
class StaffRequiredMixin(object):
@classmethod
def as_view(self, *args, **kwargs):
view = super(StaffRequiredMixin, self).as_view(*args, **kwargs)
return staff_member_required(view)
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
if not request.user.is_staff:
messages.error(
request,
'You do not have the permission required to perform the '
'requested operation.')
return redirect(settings.LOGIN_URL)
return super(StaffRequiredMixin, self).dispatch(request,
*args, **kwargs)
我想知道的是:
为什么第二种方法是重写
as_view()
方法并用 staff_member_required
包装它?这样做我们会获得任何“额外”优势吗?
我对这些 mixins 很陌生。请帮忙。
TL; DR:它们接近相同,区别在于检查
is_active
以及is_staff
和错误messages
。您可能不需要两者,因为 as_view
覆盖无论如何都不需要 dispatch
覆盖。
这些实际上只是实现同一件事的两种方法。 此代码:
class StaffRequiredMixin(object):
@classmethod
def as_view(self, *args, **kwargs):
view = super(StaffRequiredMixin, self).as_view(*args, **kwargs)
return staff_member_required(view)
...实际上可以单独使用来实现
staff_member_required
装饰器
。在这种情况下,在视图的
staff_member_required
函数中调用 as_view()
功能(即,从 URLConf 中的 as_view()
)。此代码:
class StaffRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
if not request.user.is_staff:
messages.error(
request,
'You do not have the permission required to perform the '
'requested operation.')
return redirect(settings.LOGIN_URL)
return super(StaffRequiredMixin, self).dispatch(request,
*args, **kwargs)
...通过
dispatch
方法过滤用户。您可以在 Django 代码库中看到
as_view
实际上调用了 dispatch
。这意味着,如果您同时使用两者,您实际上不会触发
if not request.user.is_staff
方法中的 dispatch
代码,因为任何未通过的用户都会在 as_view
方法中被过滤掉。第二个区别是
staff_member_required
与第一个代码的作用略有不同。如果您
查看代码,您会注意到
staff_member_required
还会检查用户的is_active
标志是否通过(不仅仅是像在您的is_staff
装饰器中那样的dispatch
)。它也不会像您的代码中那样通过 messages.error
。代码如下:
from django.contrib.auth.mixins import UserPassesTestMixin
class StaffMemberRequiredMixin(UserPassesTestMixin):
def test_func(self):
return self.request.user.is_staff
这足以使代码阻止非特权用户并重定向到
LOGIN_URL
。
希望有帮助。