首先,我们要明确我们为什么要用这个东西。
我们一般判断用户是否登录时,使用的是request.user.is_authenticate(),但是这个太单一了。只会给你一个true或者false。比如:
class UserCenterInfoView(View):
def get(self,request):
if request.user.is_authenticated():
return render(request,"user_center_info.html")
else:
return render(request,"login.html")
这段代码的意思是:如果登录,直接进入个人中心,没有登录就去登录界面。但是,我们的需求是,如果未登录了,先进入登录界面,登陆完就直接进入个人中心而不是首页,很明显,一个简单的true和false无法解决这个问题。
还有就是,如果每一个需要判断的方法里我们都要写上这样的判断语句,就显得很累赘,这时候,django系统帮我们封装了这几句话,只要我们的视图类继承这个封装好的LoginRequiredMixin类就可以了。当你继承了这个类后,你只需要写两句话就好,
login_url=’------’ 告诉他如果未登录去哪里
redirect_field_name = “-------”
def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
"""
Redirect the user to the login page, passing the given 'next' page.
"""
resolved_url = resolve_url(login_url or settings.LOGIN_URL)
login_url_parts = list(urlparse(resolved_url))
if redirect_field_name:
querystring = QueryDict(login_url_parts[4], mutable=True)
querystring[redirect_field_name] = next
login_url_parts[4] = querystring.urlencode(safe='/')
return HttpResponseRedirect(urlunparse(login_url_parts
))
我们发现,login_url没有参数,所以是肯定要传参数的。
源码是这样的,我们可以清晰的看到,当我们传入login_url后,会将这个东西传入到第5行那里,但是如果不传呢,他会启用or后边的东西, settings.LOGIN_URL,这是不是意味着我们可以在配置文件中写上LOGIN_URL = “----”,如果你不想每次继承LoginRequiredMixin后都在视图方法里对login_url进行赋值,我感觉你还是在配置文件中写上好一点。
redirect_field_name上边有默认值,所以我们可以不用传值。默认值为redirect_field_name = ‘next’,这个变量的意思是从哪来到哪去,其实说白了就是在导航栏里写下一个get类型数据,数据名称为redirect_field_name上的值,值是你是如何来到这个页面的。如果我们在前端从这个地址栏拿到值和你的请求拼接到一起,发送POST请求,我们是可以通过request.GET获得地址栏数据的(地址栏数据是GET)。
http://127.0.0.1:8000/users/login/?next=/users/center/
当我们继承后,代码就可以写成:
class UserCenterInfoView(LoginRequiredMixin, View):
def get(self,request):
return render(request, "user_center_info.html")
中间那些判断都可以省略了,因为那些判断的内容在继承的类中已经判断了。如果未登录,就会到login_url的路由中,同时,导航栏上显示你被拦截前想去的地方。登录的话,就顺着直接return走了。