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

问题描述 投票:0回答:2

我正在尝试实现 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)

我想知道的是:

  1. 为什么第二种方法是重写

    as_view()
    方法并用
    staff_member_required
    包装它?

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

我对这些 mixins 很陌生。请帮忙。

django django-views mixins
2个回答
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)

...实际上可以单独使用来实现 

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
    


0
投票

代码如下:

from django.contrib.auth.mixins import UserPassesTestMixin class StaffMemberRequiredMixin(UserPassesTestMixin): def test_func(self): return self.request.user.is_staff

这足以使代码阻止非特权用户并重定向到
LOGIN_URL

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.