1. 展示用户中心界面 class UserInfoView(View): """用户中心""" def get(self, request): """提供个人信息界面""" return render(request, 'user_center_info.html') 需求: 当用户登录后,才能访问用户中心。 如果用户未登录,就不允许访问用户中心,将用户引导到登录界面。 实现方案: 需要判断用户是否登录。 根据是否登录的结果,决定用户是否可以访问用户中心。 2. is_authenticate 判断用户是否登录 介绍: Django用户认证系统提供了方法request.user.is_authenticated()来判断用户是否登录。 如果通过登录验证则返回True。反之,返回False。 缺点:登录验证逻辑很多地方都需要,所以该代码需要重复编码好多次。 class UserInfoView(View): """用户中心""" def get(self, request): """提供个人信息界面""" if request.user.is_authenticated(): return render(request, 'user_center_info.html') else: return redirect(reverse('users:login')) 3. login_required装饰器 判断用户是否登录 Django用户认证系统提供了装饰器login_required来判断用户是否登录。 内部封装了is_authenticate 位置:django.contrib.auth.decorators 如果通过登录验证则进入到视图内部,执行视图逻辑。 如果未通过登录验证则被重定向到LOGIN_URL配置项指定的地址。 如下配置:表示当用户未通过登录验证时,将用户重定向到登录页面。 LOGIN_URL = '/login/' 1.装饰as_view()方法返回值 提示: login_required装饰器可以直接装饰函数视图,但是本项目使用的是类视图。 as_view()方法的返回值就是将类视图转成的函数视图。 结论: 要想使用login_required装饰器装饰类视图,可以间接的装饰as_view()方法的返回值,以达到预期效果。 url(r'^info/$', login_required(views.UserInfoView.as_view()), name='info'), class UserInfoView(View): """用户中心""" def get(self, request): """提供个人信息界面""" return render(request, 'user_center_info.html') 2.定义View子类封装login_required装饰器 提示:LoginRequired(object)依赖于视图类View,复用性很差。 url(r'^info/$', views.UserInfoView.as_view(), name='info'), class LoginRequired(View): """验证用户是否登陆""" @classmethod def as_view(cls, **initkwargs): # 自定义as_view()方法中,调用父类的as_view()方法 view = super().as_view() return login_required(view) class UserInfoView(LoginRequired): """用户中心""" def get(self, request): """提供个人信息界面""" return render(request, 'user_center_info.html') 3.定义obejct子类封装login_required装饰器 提示:LoginRequired(object)不依赖于任何视图类,复用性更强。 url(r'^info/$', views.UserInfoView.as_view(), name='info'), class LoginRequired(object): """验证用户是否登陆""" @classmethod def as_view(cls, **initkwargs): # 自定义as_view()方法中,调用父类的as_view()方法 view = super().as_view() return login_required(view) class UserInfoView(LoginRequired, View): """用户中心""" def get(self, request): """提供个人信息界面""" return render(request, 'user_center_info.html') 4.定义验证用户是否登录扩展类 提示:定义扩展类方便项目中导入和使用(meiduo_mall.utils.views.py) class LoginRequiredMixin(object): """验证用户是否登录扩展类""" @classmethod def as_view(cls, **initkwargs): # 自定义的as_view()方法中,调用父类的as_view()方法 view = super().as_view() return login_required(view) class UserInfoView(LoginRequiredMixin, View): """用户中心""" def get(self, request): """提供个人信息界面""" return render(request, 'user_center_info.html') 4. 登录时next参数的使用 1.next参数的效果 http://127.0.0.1:8000/login/?next=/info/ 2.next参数的作用 由Django用户认证系统提供,搭配login_required装饰器使用。 记录了用户未登录时访问的地址信息,可以帮助我们实现在用户登录成功后直接进入未登录时访问的地址。 # 响应登录结果 next = request.GET.get('next') if next: response = redirect(next) else: response = redirect(reverse('contents:index')) 5. 知识要点 判断用户是否登录依然使用状态保持信息实现。 项目中很多接口都是需要用户登录才能访问的,所以为了方便编码,我们将判断用户登录的操作封装到装饰器中。 登录时next参数的作用是为了方便用户从哪里进入到登录页面,登录成功后就回到哪里。
LoginRequired
mixin¶When using class-based views, you can achieve the same behavior as with login_required
by using the LoginRequiredMixin
. This mixin should be at the leftmost position in the inheritance list.
LoginRequiredMixin
¶raise_exception
parameter.
You can set any of the parameters of AccessMixin
to customize the handling of unauthorized users:
from django.contrib.auth.mixins import LoginRequiredMixin
class MyView(LoginRequiredMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'
Note
Just as the login_required
decorator, this mixin does NOT check the is_active
flag on a user, but the default AUTHENTICATION_BACKENDS
reject inactive users.
例:
from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): # login_url = '/login/' # redirect_field_name = 'redirect_to' def get(self, request): return render(request, 'authenticated_page.html')