用于基于 class 的通用视图的 Django mixins

Django mixins for class-based-generic views

我正在尝试实施 staff_member_required 混入:

以下是我找到的两种方法:

第一个:

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)

我想知道的是:

  1. 为什么第二种方法是覆盖 as_view() 方法并用 staff_member_required 包装它?

  2. 我们这样做有什么'additional'优势吗?

我是这些混音的新手。请帮忙。

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 decorator。在这种情况下,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 actually calls dispatch。这意味着如果你同时使用两者你实际上永远不会触发dispatch方法中的if not request.user.is_staff代码,因为任何没有通过的用户都会在as_view方法中被过滤掉了。

第二个区别是 staff_member_required 与第一个代码的作用略有不同。如果你 check out the code,你会注意到 staff_member_required 还会检查用户的 is_active 标志是否通过(不像你的 dispatch 装饰器中那样只是 is_staff)。它也不会像您的代码中那样传递 messages.error