用户登陆:
在这里我使用Django自带的auth用户认证系统调用authenticate、login函数来完成网站的登陆,以下是对form表单中的get和post请求进行分析处理。
视图函数:
1 def user_login(request): 2 if request.method == 'POST': #是post请求就取出form表单中传过来的用户名和密码 3 4 user_name = request.POST.get('username', '') 5 pass_word = request.POST.get('password', '') 6 user = authenticate(username=user_name, password=pass_word) 7 #调用authenticate函数来验证用户名和密码合法性,authenticate函数接受2个参数username和passsword 8 #authenticate方法验证合法返回user对象,不合法返回None 9 if user is not None: 10 login(request, user)#调用login函数完成user对象登陆,login方法传入request和user对象 11 return render(request, 'index.html') #登陆成功返回首页 12 else: 13 context = { 14 'msg_error': '用户名或密码错误!'#如果为None返回login页面 15 } 16 elif request.method == 'GET': #是get请求直接返回login页面 17 context = { 18 19 } 20 return render(request, 'login.html', context)
authenticate函数只是验证用户名和密码的合法性并生成一个合法证书,完成网站的登陆需要使用login函数并传入request和一个合法的user对象参数。
加入表单验证:
上面的代码只是处理了用户名密码正确错误的合法性,但没有处理不规范的用户名密码如密码为空、小于6位等,通过加入表单验证可以有效解决这些问题,减轻对数据库的查询负担。在本目录新建forms.py通过django自带的表单功能来继续完善登陆机制。
1 #forms.py 2 3 from django import forms 4 5 class LoginForm(forms.Form): #继承forms.FOrm 6 username=forms.CharField(required=True) #设置required=True表示是必填字段 7 password=forms.CharField(required=True,min_length=6,max_length=15)#设置必填字段,最小字符长度6,最大15
在用户登陆逻辑中引入LoginForm并进行实例化,传入request.POST字典(包含前端传进的username和password),login_form对象下有一个is_valid方法可以来验证是否符合我们设置的LoginForm表单验证需求。
1 #views.py 2 3 def user_login(request): 4 if request.method == 'POST': #是post请求就取出form表单中传过来的用户名和密码 5 login_form=LoginForm(request.POST)#实列化Login_Form传入request.POST字典 6 if login_form.is_valid():#调用实例下的is_valid()方法验证是否符合表单的需求 7 user_name = request.POST.get('username', '') 8 pass_word = request.POST.get('password', '') 9 user = authenticate(username=user_name, password=pass_word) 10 # 调用authenticate方法来验证用户名和密码合法性,authenticate方法接受2个参数username和passsword 11 # authenticate方法验证合法返回user对象,不合法返回None 12 if user is not None: 13 login(request, user) # 调用login方法完成user对象登陆,login方法接受request和一个合法的user对象参数 14 return render(request, 'index.html') # 登陆返回首页 15 else:#当user对象用户名密码不正确返回login页面, 16 context = { 17 'error_msg': '用户名或密码错误!' 18 } 19 return render(request,'login.html',context) 20 else:#未通过form表单验证返回登陆页面,并显示错误信息 21 context={ 22 'login_form':login_form 23 } 24 return render(request,'login.html',context) 25 elif request.method == 'GET': #是get请求直接返回login页面 26 context = { 27 28 } 29 return render(request, 'login.html', context)
模板渲染:
通过视图逻辑中传到前端的错误信息context字典变量在模板中使用DTL语法渲染,{% for key,error in login_form.error.items %} {{ error }} {% endfor %}
1 #login.html 2 <div class="fl form-box"> 3 <h2>帐号登录</h2> 4 <form action="/login/" method="post" autocomplete="off"> 5 <input type='hidden' name='csrfmiddlewaretoken' value='mymQDzHWl2REXIfPMg2mJaLqDfaS1sD5' /> 6 <div class="form-group marb20 ">{% if login_form.errors.username %}errorput{% endif %} 7 <label>用 户 名</label> 8 <input name="username" id="account_l" type="text" placeholder="手机号/邮箱" /> 9 </div> 10 <div class="form-group marb8 {% if login_form.errors.password %}errorput{% endif %}"> 11 <label>密 码</label> 12 <input name="password" id="password_l" type="password" placeholder="请输入您的密码" /> 13 </div> 14 <div class="error btns login-form-tips" id="jsLoginTips"></div> 15 {% for key ,error in login_form.errors.items %} 16 {{ error }} 17 {% endfor %} 18 {{ error_msg }} 19 20 <div class="auto-box marb38"> 21 22 <a class="fr" href="forgetpwd.html">忘记密码?</a> 23 </div> 24 <input class="btn btn-green" id="jsLoginBtn" type="submit" value="立即登录 > " /> 25 <input type='hidden' name='csrfmiddlewaretoken' value='5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy' /> 26 {% csrf_token %} 27 </form> 28 <p class="form-p">没有慕学在线网帐号?<a href="register.html">[立即注册]</a></p> 29 </div>
函数视图改造为类视图:
上面一直是使用函数视图的方式来处理get和post请求,实际上工作中采用类视图更加方便,从from django.views.generic import View引入View。
构造我们自己Login类视图需要继承View重写我们自己的get和post方法,然后类视图可以根据request来自动调用get还是post。
1 #views.py 2 from django.views.generic import View 3 4 class LoginView(View): 5 def get(self,request):是get请求返回登陆页 6 return render(request,'login.html') 7 8 def post(self,request):#是post请求取出form表单中传过来的用户名和密码 9 login_form=LoginForm(request.POST)#实列化Login_Form传入request.POST字典 10 if login_form.is_valid():#调用实例下的is_valid()方法验证是否符合表单的需求 11 user_name=request.POST.get('username','') 12 pass_word=request.POST.get('password','') 13 user=authenticate(username=user_name,password=pass_word) 14 #调用authenticate方法来验证用户名和密码合法性。 15 # authenticate方法验证合法返回user对象,不合法返回None 16 if user is not None: 17 login(request,user) #调用login函数登陆 18 return render(request,'index.html') 19 else:#当user对象用户名密码不正确返回login页面, 20 context={ 21 'error_msg':'密码或账号错误' 22 } 23 return render(request,'login.html',context) 24 else:# login_form用户名和密码不符合form表单, 返回登录页面, 并提示错误信息 25 26 return render(request,'login.html',{'login_form':login_form})
在url配置中因为只允许函数视图,不允许类视图,因此我们要采用类视图下的.as_view方法把类视图改造为函数视图。
path("login/",LoginView.as_view(),name='login'),