django之简单验证码实现与form表单钩子函数补充
本篇主要讲解简单的验证码实现,验证码使用基本都是找现成的组件来实现,用代码实现这个简单功能主要是了解了解验证码内部的实现。
本篇导航:
1、首先用bootstrap布一个上图简单的页面
<div class="container"> <div class="row"> <div class="col-md-5 col-md-offset-3"> <h1>账户登录</h1><span class="error"></span> <form> {% csrf_token %} <div class="form-group"> <label for="username">用户名</label> <input type="text" class="form-control" id="username" placeholder="username"> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" class="form-control" id="password" placeholder="password"> </div> <div class="row validCode"> <div class="col-md-6"> <div class="form-group"> <label for="validCode">验证码</label> <input type="text" class="form-control validCode_text" id="validCode" placeholder="validCode"> </div> </div> <div class="col-md-6"> <img class="validCode_img" src="/get_validCode_img/" alt="" width="200px" height="50px"> </div> </div> <input type="button" value="登录" class="btn btn-primary" id="subBtn"> </form> </div> </div> </div>
2、在视图函数里写一个验证码
首先下载图像处理的模块
pip install PIL
pip install pillow
第一个无法下载的话就下载第二个他们的引用都是from PIL没有区别 实现随机验证码图片代码:
def get_validCode_img(request): from io import BytesIO #内存 import random from PIL import Image,ImageDraw,ImageFont img = Image.new(mode="RGB", size=(120, 40), color=(random.randint(0,255),random.randint(0,255),random.randint(0,255))) draw=ImageDraw.Draw(img,"RGB") font=ImageFont.truetype("static/font/kumo.ttf",25) valid_list=[] #随机五位数字大小写字母 for i in range(5): random_num=str(random.randint(0,9)) random_lower_zimu=chr(random.randint(65,90)) random_upper_zimu=chr(random.randint(97,122)) random_char=random.choice([random_num,random_lower_zimu,random_upper_zimu]) draw.text([5+i*24,10],random_char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font) valid_list.append(random_char) f=BytesIO() img.save(f,"png") data=f.getvalue() #在内存取值 valid_str="".join(valid_list) # print(valid_str) request.session["keepValidCode"]=valid_str #存入session return HttpResponse(data)
1、ajax实现验证
<script src="/static/jquery-3.2.1.js"></script> <script> $("#subBtn").click(function () { $.ajax({ url: "/login/", type: "POST", data: { "username" : $("#username").val(), "password" : $("#password").val(), "validCode" : $("#validCode").val(), "csrfmiddlewaretoken" : $("[name='csrfmiddlewaretoken']").val() }, success: function (data) { var response = JSON.parse(data); if (response["is_login"]) { location.href = "/index/" } else { $(".error").html(response["error_msg"]).css("color", "red") } } }) }) </script>
2、view视图函数
使用django中的自带用户验证需要导入模块
from django.contrib import auth
具体代码
def log_in(request): if request.is_ajax(): username=request.POST.get("username") password=request.POST.get("password") validCode=request.POST.get("validCode") login_response={"is_login":False,"error_msg":None} if validCode.upper()==request.session.get("keepValidCode").upper(): user=auth.authenticate(username=username,password=password) if user: login_response["is_login"]=True request.session["IS_LOGON"] = True request.session["USER"] = username # auth.login(request,user) 与上面两步自己写session相同 else: login_response["error_msg"] = "username or password error" else: login_response["error_msg"]='validCode error' import json return HttpResponse(json.dumps(login_response)) return render(request,"login.html")
首页视图函数
def index(request): ret=request.session.get("IS_LOGON",None) if ret : username=request.session.get("USER") return render(request, "index.html",{"username":username}) return redirect("/login/") # if not request.user.is_authenticated(): # return redirect("/login/") # return render(request,"index.html") # 与上面auth.login(request,user)对应使用 # 此时在template页面使用{{ request.user.username }}显示用户直接使用不需传值
只对钩子函数做简单补充想看具体Form组件请前往:http://www.cnblogs.com/liluning/p/7822526.html
from django import forms class LoginForm(forms.Form): username = forms.CharField(label='username', max_length=100) password = forms.CharField(label='password', max_length=100) #钩子函数为对应字段添加判断条件 def clean_username(self): if len(self.cleaned_data.get("username"))>5: print(self.cleaned_data.get("password")) return self.cleaned_data.get("username") def clean_password(self): pass #全局钩子函数 def clean(self): if self.cleaned_data["password"] == self.cleaned_data["repeat_password"]: return self.cleaned_data