【问题标题】:Restricting all the views to authenticated users in Django将所有视图限制为 Django 中经过身份验证的用户
【发布时间】:2018-07-02 15:08:57
【问题描述】:

我是 Django 新手,我正在开发一个项目,该项目有一个登录页面作为其索引和一个注册页面。其余页面都必须限制为登录用户,如果未经身份验证的用户试图访问他们,他/她必须被重定向到登录页面。

我看到@login_required 装饰器会将单个视图限制为已登录用户,但有没有更好的方法来限制所有视图并且只有少数视图可供未经身份验证的用户使用?

【问题讨论】:

标签: python django


【解决方案1】:

你可以写一个中间件:

from django.contrib.auth.decorators import login_required

def login_exempt(view):
    view.login_exempt = True
    return view


class LoginRequiredMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        return self.get_response(request)

    def process_view(self, request, view_func, view_args, view_kwargs):
        if getattr(view_func, 'login_exempt', False):
            return

        if request.user.is_authenticated:
            return

        # You probably want to exclude the login/logout views, etc.

        return login_required(view_func)(request, *view_args, **view_kwargs)

您将中间件添加到您的 MIDDLEWARES 列表中并装饰您不希望使用 login_exempt 进行身份验证的视图。

【讨论】:

  • 为什么在这里使用setattr?只是好奇。
  • @wim:没有真正的原因。不使用setattr 更清楚。
  • 您评论了一些关于排除某些视图的内容。我应该代替您的评论还是只使用 login_excempt?
  • @MohammedFarahmand:你不能装饰存在于其他包中的视图(比如内置的 Django 登录页面)。您必须手动排除它们。
  • @Blender 如何手动排除登录视图?
【解决方案2】:

...有没有更好的方法来限制所有视图,并且只有少数视图可供未经身份验证的用户使用?

是的。是时候学习class based views了。定义一个需要登录的基类,并使任何经过身份验证的端点都继承这个基类,而不是使用基于函数的视图并在每个函数上进行装饰。

实现中流行的设计模式是使用mixin class

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

如果视图使用了这个 mixin,所有非认证用户的请求都会被重定向到登录页面。

【讨论】:

  • 虽然我同意 CBV 的一般优势,但这仍然需要将 mixin 添加到每个受影响的视图中(很像装饰器)。
  • 是的,这很好,因为它更明确。另一种选择是定义 LoginRequired 视图并从它继承而不是视图。
  • @schwobaseggl 不一定。您可以定义一个带有登录处理的基类,并继承LoginRequiredView 而不是Django 的通用视图。如果您发现自己经常使用装饰器,这是一种比装饰更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 2019-06-28
  • 1970-01-01
  • 2020-11-15
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
相关资源
最近更新 更多