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

Sum*_*Jha 4 django mixins django-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)
Run Code Online (Sandbox Code Playgroud)

第二:

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)
Run Code Online (Sandbox Code Playgroud)

我想知道的是:

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

  2. 这样做我们是否获得任何“额外”优势?

我是这些 mixin 的新手。请帮忙。

YPC*_*ble 5

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)
Run Code Online (Sandbox Code Playgroud)

...实际上可以单独使用来实现staff_member_required装饰器。在这种情况下,该staff_member_required功能会在视图的函数中被调用as_view()(即,as_view()在您的 URLConf 中)。

这段代码:

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)
Run Code Online (Sandbox Code Playgroud)

...在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在您的代码中传递类似内容。