Django之验证码的实现,简单快捷的方法
实现验证码随网页变动即时刷新,实现有期限时间
请确保安装好pillow
直接show code:
0、路由urs.py
from django.urls import path, re_path
from . import views
urlpatterns = [re_path(r'^test/$', views.testpage, name='test'),re_path(r'^captcha/$', views.captcha, name='captcha'),
]
1、定义生成验证码views.py
import os, random, time, string, io
from django.shortcuts import render
from django.http import HttpResponse
from PIL import Image, ImageDraw, ImageFont
# 生成验证码,# 可以直接可以在html中的img引用
def captcha(request):# 定义背景颜色、宽、高bgcolor = (random.randrange(20, 100), random.randrange(20, 100), random.randrange(20, 100))width = 100height = 50# 创建画面对象img = Image.new('RGB', (width, height), bgcolor)# 创建画笔对象draw = ImageDraw.Draw(img)# 调用画笔的point()函数绘制验证码的干扰点for i in range(0, 100):xy = (random.randrange(0, width), random.randrange(0, height))fill = (random.randrange(0, 255), random.randrange(0, 255), 55)draw.point(xy, fill=fill)# 定义验证码的备选值_str = string.digits + string.ascii_letters# 随机取四个值作为验证码rand_codes = ''.join(random.sample(_str, 4))# 定义字体大小size = int(min(width / len(rand_codes), height))# 构造字体对象font = ImageFont.truetype(r'C:\Windows\Fonts\Arial.ttf', size)# 构造字体颜色,四个字颜色不同for i in range(4):fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))draw.text((i * 25, 2), rand_codes[i], font=font, fill=fontcolor)# 释放画笔del draw# # 将验证码缓存入session,后面做进一步验证,注意应该在这里存入的时候变为小写,# 否则验证码过期就变成了空,再进行lower()操作会抛出异常request.session['verify_code'] = rand_codes.lower()# 验证码有效时间60秒request.session.set_expiry(60)print("生成的验证码是:", rand_codes)print("它应该是与session存的验证码一样:", request.session['verify_code'])buf = io.BytesIO()img.save(buf, 'png')# 将内存中的图片数据返回给客户端,MIME类型为png图片return HttpResponse(buf.getvalue(), 'image/png')# 这样也行# return HttpResponse(buf.getvalue(), 'jpg')
关键点在于io.BytesIO()函数和它的getvalue()函数
BytesIO()使用的是Binary I/O(也叫buffered I/O)的方法,它的处理对象必须是字节类对象(bytes-like object),生成的对象是字节(bytes),这个过程不执行解码、编码和换行转换。这种类型的数据流可以用于所有非文本类的的数据(也就是二进制文件或二进制读取的文本,如图片、gif,以二进制读取的.txt,.py,.html等文件)。
而getvalue()返回储存在缓存中对象整个内容的字节
总之只要理解为:BytesIO()直接以二进制方式读取jpg、png、gif等文件并将它存于缓存中,而getvalue()方法则是将它从缓存中取出来,还原成原来的样子显示给我们看。
2、路由导航函数views.py
# 测试页
def testpage(request):verify_msg = ''_captcha_submit = request.POST.get('verify_code').lower()# 注意这里提交的code需要小写,而服务器的code已经小写,# 这样分开做是为了避免当验证码过期了变为空值取不到session抛出异常_captcha_server = request.session.get('verify_code')if _captcha_server == _captcha_submit:return render(request, 'axf/test.html', {"msg": "验证成功"})else:verify_msg = '验证失败'return render(request, 'testapp/test.html', {"msg": verify_msg})
3、模板下的HTML页test.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>测试页面</title>
</head>
<body><form action="/test/" method="post"><img src="/captcha/" alt="验证码"/><div><label><input type="text" name="verify_code" placeholder="请输入图片中验证码"></label><input type="submit" value="验证"/></div></form><a>验证结果:</a><p style="color: red">{{msg}}</p>
</body>
</html>
展示结果:
验证码设置了60秒过期,如果过了60秒再输入验证码是不会成功的