django为基于类的视图添加用户身份验证检查

时间:2013-05-01 11:41:28

标签: django django-class-based-views class-based-views

我的应用中有很多基于类的视图。其中大多数只能由经过身份验证的工作人员用户访问。如何轻松添加许多基于类的视图的用户检查?

对于标准函数视图,我添加了这样的装饰器:

def only_staff_allowed(fn):
    '''decorator'''
    def wrapped(request, *args, **kwargs):
        if request.user.is_staff:
            return fn(request, *args, **kwargs)
        else:
            return HttpResponseRedirect(reverse('moderator:login'))
    return wrapped

@only_staff_allowed
def dashboard(request):
    ''' now accessible only by staff users '''
    return render(request, 'moderator/dashboard.html', {})

我怎样才能做类似基于类的视图的事情呢?

class AddressesAddList(ListView):
    template_name = 'moderator/addresses/add_list.html'
    queryset = Address.objects.filter(need_moderating=True)
    paginate_by = 100

我应该添加一些mixins还是覆盖一些方法?或者我可以装饰一些东西吗?

3 个答案:

答案 0 :(得分:4)

您应该修饰基于类的视图的调度方法。见下文。

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

class ProtectedView(TemplateView):
    template_name = 'secret.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectedView, self).dispatch(*args, **kwargs)

请参阅文档here

答案 1 :(得分:4)

实际上,至少有三种方法可以避免为您要求登录的每个视图类装饰dispatch方法。

如果您只有几个这样的视图,您可以在URLconf中使用该装饰器,如下所示:

url(r"^protected/$", login_required(ProtectedView.as_view()), name="protected_view"),

或者,如果您有更多要保护的视图,请使用django-braces中的LoginRequiredMixin

from braces.views import LoginRequiredMixin

class ProtectedView(LoginRequiredMixin, TemplateView):
    template_name = 'secret.html'

而且,如果你有很多观点需要保护,你应该使用中间件一次性覆盖一堆视图;类似的东西:

class RequireLoginMiddleware(object):
    """Requires login for URLs defined in REQUIRED_URLS setting."""
    def __init__(self):
        self.urls = tuple([re.compile(url) for url in REQUIRED_URLS])
        self.require_login_path = getattr(settings, 'LOGIN_URL', '/accounts/login/')
    def process_request(self, request):
        if not request.user.is_authenticated() and request.path != self.require_login_path:
            for url in self.urls:
                if url.match(request.path):
                    return HttpResponseRedirect(u"{0}?next={1}".format(self.require_login_path, request.path))

答案 2 :(得分:2)

您可以使用LoginRequiredMixin。这会将未经身份验证的用户重定向到页面集。

from braces.views import LoginRequiredMixin

class DashboardIndex(LoginRequiredMixin, TemplateView):

template_name = 'dashboard/index.html'
login_url = 'action:login' #Where you must set the page else will use default.
raise_exception = False

https://django-braces.readthedocs.org/en/latest/access.html#loginrequiredmixin