【发布时间】:2018-07-02 15:08:57
【问题描述】:
我是 Django 新手,我正在开发一个项目,该项目有一个登录页面作为其索引和一个注册页面。其余页面都必须限制为登录用户,如果未经身份验证的用户试图访问他们,他/她必须被重定向到登录页面。
我看到@login_required 装饰器会将单个视图限制为已登录用户,但有没有更好的方法来限制所有视图并且只有少数视图可供未经身份验证的用户使用?
【问题讨论】:
我是 Django 新手,我正在开发一个项目,该项目有一个登录页面作为其索引和一个注册页面。其余页面都必须限制为登录用户,如果未经身份验证的用户试图访问他们,他/她必须被重定向到登录页面。
我看到@login_required 装饰器会将单个视图限制为已登录用户,但有没有更好的方法来限制所有视图并且只有少数视图可供未经身份验证的用户使用?
【问题讨论】:
你可以写一个中间件:
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?只是好奇。
setattr 更清楚。
...有没有更好的方法来限制所有视图,并且只有少数视图可供未经身份验证的用户使用?
是的。是时候学习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,所有非认证用户的请求都会被重定向到登录页面。
【讨论】:
LoginRequiredView 而不是Django 的通用视图。如果您发现自己经常使用装饰器,这是一种比装饰更好的方法。