用户登录验证+url别名反推

一、用户登录验证

  - 验证两次密码输入是否一致

  - 自定制密码验证规则(必须包含字母、数字和特殊字符)

  - 验证码的使用

  - 免登录期限

views.py

  1 from django.http import HttpResponse
  2 from django.shortcuts import render
  3 from django.urls import reverse
  4 from io import BytesIO
  5 from django.forms import fields
  6 from django import forms
  7 from django.core.exceptions import ValidationError,NON_FIELD_ERRORS   # NON_FIELD_ERRORS == __all__
  8 import json
  9 
 10 from utils.check_code import create_validate_code
 11 
 12 def index_get(request,**kwargs):
 13     """
 14     无用,测试通过url别名反推url
 15     :param request: 
 16     :param kwargs: 
 17     :return: 
 18     """
 19     print(kwargs)
 20     current_path = reverse("index_all",kwargs=kwargs)
 21     # print(current_path)
 22     return HttpResponse("nihao")
 23 
 24 class Login(forms.Form):
 25     """
 26     form组件验证用户输入
 27     """
 28     user = fields.CharField(
 29         max_length=32,
 30         error_messages={
 31             "required":"用户名不能为空"
 32         }
 33     )
 34     pwd = fields.RegexField(
 35         '^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\%\^\&\*\(\)])[0-9a-zA-Z!@#$\%\^\&\*\(\)]{8,32}',
 36         min_length=8,
 37         max_length=32,
 38         error_messages={
 39             "required":"密码不能为空",
 40             "invalid":"密码必须包含数字字符串和特殊字符",
 41             "min_length":"密码长度不得小于8位",
 42             "max_length":"密码长度不得大于32位",
 43         }
 44     )
 45     #再次输入的密码只是为了验证一致性,可以不自定制匹配
 46     pwd_again = fields.RegexField(
 47         '^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\%\^\&\*\(\)])[0-9a-zA-Z!@#$\%\^\&\*\(\)]{8,32}',
 48         min_length=8,
 49         max_length=32,
 50         error_messages={
 51             "required":"密码不能为空",
 52             "invalid":"密码必须包含数字字符串和特殊字符",
 53             "min_length":"密码长度不得小于8位",
 54             "max_length":"密码长度不得大于32位",
 55         }
 56     )
 57     check_code = fields.CharField()
 58     def clean(self):
 59         # self.cleaned_data["pwd"]   报错
 60         a = self.cleaned_data.get("pwd")
 61         b = self.cleaned_data.get("pwd_again")
 62         if a == b:
 63             pass
 64         else:
 65             raise ValidationError("密码不一致")
 66 
 67 # Create your views here.
 68 def index(request):
 69     if request.method == "GET":
 70         return render(request, "index.html")
 71     else:
 72         msg = {"status":True,"error":None,"check_code":None}
 73         # print(request.POST,request.session.get("code"))
 74         login_test = Login(request.POST)
 75         if login_test.is_valid():
 76             request.session["user"] = login_test.cleaned_data.get("user")
 77             if request.POST.get("box"):
 78                 # 设置免登录,不完全
 79                 request.session.set_expiry(60 * 60 * 24 * 3)  # 设置session的生命周期,单位为秒
 80                 # print(login_test.errors.get("__all__"))
 81             if (request.session.get("code")).lower() == (login_test.cleaned_data.get("check_code")).lower():
 82                 msg["check_code"] = True
 83         else:
 84             # 不管通过不通过,验证码都应该被验证,但放在is_valid外面又无法获取用户输入的验证码
 85             if (request.session.get("code")).lower() == (login_test.cleaned_data.get("check_code")).lower():
 86                 msg["check_code"] = True
 87             msg["status"] = False
 88             msg["error"] = login_test.errors
 89         return HttpResponse(json.dumps(msg))
 90 
 91 def create_checkcode(request):
 92     img,code = create_validate_code()
 93     f = BytesIO()     # 获取一块内存空间
 94     img.save(f,'PNG')  # 将验证码生成函数发送来的图片保存在这块空间中,img是一个对象
 95     # print(code)
 96     # print(request.session.keys())
 97     request.session["code"] = code   # 将验证码字符串保存在session中以供验证输入时使用
 98     request.session.set_expiry(20)   # 验证码20秒后失效
 99     # return render(request,"login.html",{"img":f.getvalue()})    # 乱码
100     return HttpResponse(f.getvalue())  # 获取把保存在这块内存中的数据
101 
102 def log_success(request):
103     """
104     用户登陆成功返回欢迎页面,显示用户名
105     :param request: 
106     :return: 
107     """
108     print(request.session.get("user"))
109     return render(request,"log_success.html",{"user":request.session.get("user")})
View Code

index.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
 7     <style>
 8     </style>
 9 </head>
10 <body>
11 
12 <div style="width: 500px;background-color: #2aabd2;height: 400px;margin: 10px auto">
13     <form class="form-horizontal" action="/index/" method="post" id="fr">
14         {% csrf_token %}
15       <div class="form-group ipu">
16         <label for="inputEmail3" class="col-sm-2 control-label">用户名</label>
17         <div class="col-sm-10">
18             <input type="text" placeholder="用户名" name="user">
19             <span id="user"></span>
20         </div>
21       </div>
22       <div class="form-group ipu">
23         <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
24         <div class="col-sm-10">
25             <input type="password" placeholder="密码" name="pwd">
26             <span id="pwd"></span>
27         </div>
28       </div>
29       <div class="form-group ipu">
30         <label for="inputPassword3" class="col-sm-2 control-label">再次输入</label>
31         <div class="col-sm-10">
32             <input type="password" placeholder="密码" name="pwd_again">
33             <span id="pwd_again"></span>
34         </div>
35       </div>
36       <div class="form-group ipu">
37         <label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
38         <div class="col-sm-10">
39             <input type="text" placeholder="验证码" name="check_code">
40             <img src="../create_checkcode" alt="" onclick="img(this)">
41             <span id = "check_code"></span>
42         </div>
43       </div>
44         <div class="form-group ipu">
45         <div class="col-sm-10">
46             <input type="checkbox" value="1" name="box">
47             <span>三天内免登录</span>
48         </div>
49       </div>
50 
51     </form>
52     <button type="button" class="btn btn-primary" onclick="sub()" style="margin: 10px 100px">登录</button>
53     </div>
54 
55 <script src="/static/jquery-3.1.1.js"></script>
56 <script src="/static/bootstrap/js/bootstrap.js"></script>
57 <script>
58     function sub() {
59         $.ajax({
60             url:'/index/',
61             data:$("#fr").serialize(),   //取出form表单中的所有用户输入
62             type:"POST",
63             datatype:"JSON",   //好像无用,还是要使用JSON.parse(),不然无法获取
64             success:function (arg) {
65                 var data = JSON.parse(arg);
66                 if(data.status){
67                     // 重定向url
68                     window.location.replace("../log_success")
69                 }
70 {#                console.log(data.error);#}
71                 for(key in data.error){
72 {#                    console.log(data.error[key][0]);#}
73                     document.getElementById(key).innerHTML = data.error[key][0];
74                 }
75                 if(!data.check_code){
76                     $("#check_code").html("验证码错误")
77                 }
78 
79             }
80         })
81     }
82     function img(ths) {
83         console.log(111);
84         //给url加?可以重新获取
85         ths.src = ths.src+"?";
86 {#        $(ths).attr("src","../create_checkcode");#}
87     }
88 </script>
89 
90 </body>
91 </html>
View Code

二、url别名反推

name是别名通过别名在views.py和html中都可以反向生成url
在views.py中
from django.urls import reverse
对于有分组名的url
current_path = reverse("name",kwargs = {"分组名":参数})
没有的
current_path = reverse("name",args = (参数1,参数2......))
在html中
{% url "name" 分组名 = 参数%} 或者没有分组名的时候直接写参数

posted @ 2019-10-31 08:43  pywhy  阅读(369)  评论(0编辑  收藏  举报