用戶登陸:
在這里我使用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'),