django练手(十五):实现某些页面不登录不能访问的功能
本节实现的功能是:不登录,访问修改密码的页面,自动跳转到登录界面。登录后,网页自动跳转到修改密码的页面。
一.功能描述及实现思路
这个功能主要依靠django的login_required方法实现。
功能描述和实现思路:
- 没有登录的用户访问受保护的视图时,网页自动跳转到登录地址。
- 网页跳转时,会以url传参的方式自动在url后加上
?next=原访问地址
。 - 登录模板接收url传递过来的参数,并在发起登录请求时以url传参的方式把这个参数传到后端。
- 后端视图接收这个参数,登录用户账号。把next参数处理后再返回前端。前端进行跳转动作。
接下来,我以修改密码的页面为例,实现不登录不能访问的功能。
二.功能实现
- 在app-views-app-views.py 文件中引入login_required方法。引入的代码如下:
from django.contrib.auth.decorators import login_required
-
在app-views-app-views.py 文件中找到change_password视图,该视图的作用是修改密码。在该视图上以装饰器的形式使用login_required方法,以达到不登录,就不能访问修改密码页面的效果。具体代码如下:
@login_required # 以装饰器的形式使用login_required方法 # 修改密码视图 def change_password(request): if request.method == 'GET': fields = ChangePassword(request) return render(request, 'app/change_password.html', {'fields': fields}) if request.method == 'POST': data = request.POST fields = ChangePassword(request, data) if fields.is_valid(): # 获取清洗过的新密码 new_password = fields.cleaned_data.get('new_password', '') # 获取当前用户 user = request.user # 用新密码修改当前用户的密码 user.set_password(new_password) # 保存当前用户 user.save() # 当前用户重新登录 login(request, user) return JsonResponse({'status': True}) else: return JsonResponse({'status': False, 'errors': fields.errors})
-
在settings.py 文件中指定跳转地址。操作方法如下:
在settings.py文件末尾加上LOGIN_URL = '/app/login/'
,告诉django,如果没有登录的用户访问了,就跳转到'/app/login/'这个地址,这个地址是登录地址。 -
修改登录视图的代码,使之能够接收跳转前的地址,并把该地址返回给前端页面,用于登录后的跳转。
login_required方法跳转时,会自动在网址上加上?next=原访问地址
。具体到本项目,
该地址变成http://127.0.0.1:8000/app/login/?next=/app/changepwd/
。接下来,就是修改app-views-app-views.py文件中的login_view
视图。
代码如下:def login_view(request): """ 功能描述: 1、获取网址中携带的next参数的值,这个值是访问登录页面之前访问的地址; 2、如果是GET方法访问该视图,返回登录表单。 3、如果是POST方法访问该视图,则用LoginForm进行数据验证,如果验证通过,进入登录状态。如果验证不通过,返回错误信息。 """ # 获取url中携带的next参数 next_url = request.GET.get('next', '') if request.method == 'POST': data = request.POST fields = LoginForm(request, data) # 登录信息校验成功 if fields.is_valid(): # 并且next的值不为空 if next_url: # 把登录状态的参数status的值设置成True,把next值返回给前端 return JsonResponse({"status": True, "next_url": next_url}) else: # 把登录状态的参数status的值设置成False,把首页的地址返回给前端 return JsonResponse({"status": True, "next_url": '/'}) else: return JsonResponse({"status": False, "errors": fields.errors}) if request.method == 'GET': fields = LoginForm(request) return render(request, 'app/login.html', {'fields': fields})
-
ajax执行成功后,前端接收next的值,并执行跳转。
实现思路:
①、在用户点击登录按钮后,前端通过ajax的post方法把登录数据发送给后端。同时,url上携带了next参数。
②、前端在收到后端的响应后,判断是否登录成功。如果登录成功,就进行跳转。依据后端返回的跳转地址信息,或跳转到登录前页面,或跳转到主页。
③、如果没有登录成功,则把登录的错误信息显示在页面上。
具体代码如下:<script> $(document).ready(function () { btnSubmitClick() }) function btnSubmitClick() { $("#btnSubmit").click(function () { $(".error-msg").empty(); //清除报错信息 let data = $("#login_form").serialize(); //获取form表单的数据 $.ajax({ /*ajax请求发送的地址。与一般的地址不同,这个地址获取了GET请求访问该页面时携带的next参数。在发送ajsx请求时,把next通过url传参的方式传到后台。 */ url: "{% url 'app:login' %}?next={{ request.GET.next }}", type: "POST", //请求的方式是POST请求 data: data, //请求的数据 async: true, //异步方式请求 dataType: "json", //返回数据的格式是json // 接下来是请求成功之后执行的函数 success: function (res) { if (res.status) { location.href=res.next_url; //如果登录成功,则挑转到next_url代表的地址 console.log(res.next_url); } else { //请求不成功,把错误信息显示在页面上 $.each(res.errors, function (key, value) { $("#id_" + key).next().text(value); }) } }, // 接下来是请求失败执行的函数 errors: function () { console.log("请求失败"); } }) }) } </script>