验证码登录
import os
from random import randint, sample
from PIL import ImageFont, Image, ImageDraw
from io import BytesIO
# 验证码类
from show_code import settings
class VerfiyCode:
def __init__(self,width=100,height=40,len=4):
"""
系统初始化
:param width: 验证码图片宽度
:param height: 验证码图片高度
:param len: 验证码长度
"""
self.width = width if width > 50 else 100
self.height = height if height > 30 else 40
self.len = len if len >= 4 else 4
self._code = '' #验证码字符串
self.__pen = None #画笔
@property
def code(self):
return self._code
def output(self):
"""
输出验证码
:return: 验证码图片的二进制流
"""
# 1 创建画布
im = Image.new('RGB',(self.width,self.height),self.__randColor(120,200))
self.__pen = ImageDraw.Draw(im) #产生画笔
# 2 产生验证码字符串
self.generateCode()
print(self._code,"kkkk")
# 3 画验证码
self.__drawCode()
# 4. 画干扰点
self.__drawpoint()
# 5 画干扰线
self.__drawline()
# 6 返回图片
im.save('vc.png','PNG')
buf = BytesIO()
im.save(buf,'png')
res = buf.getvalue()
buf.close()
return res
def __randColor(self,low,high):
return randint(low,high),randint(low,high),randint(low,high)
def generateCode(self):
"""
产生纯数字验证码
:return: 无
"""
num = ''
for i in range(self.len):
num += str(randint(0,9))
self._code = num
def __drawCode(self):
"""
画验证码
:return:
"""
path = os.path.join(settings.STATICFILES_DIRS[0],'font/STHUPO.TTF')
# print(path)
font1 = ImageFont.truetype(path,size=20,encoding='utf-8')
# print(font1)
# 一个字符宽度
width = (self.width - 20)/self.len
for i in range(self.len):
x = 10 + i * width + width / 4
y = randint(5,self.height-25)
self.__pen.text((x,y),self._code[i],font=font1,fill=self.__randColor(0,100))
def __drawpoint(self):
for i in range(300):
x = randint(1,self.width - 1)
y = randint(1,self.height - 1)
self.__pen.point((x,y),fill=self.__randColor(60,160))
def __drawline(self):
print(self._code)
for i in range(6):
# 起点坐标
start = (randint(1,self.width - 1),randint(1,self.height - 1))
end = (randint(1,self.width - 1),randint(1,self.height - 1))
self.__pen.line([start,end],fill=self.__randColor(120,200))
# class StrCode(VerfiyCode):
# def generateCode(self):
# s1 = 'QWERTYUPASDFGHJKLZXCVBNMqwertyupasdfghjklzxcvbnm'
# res = sample(s1,self.len)
# res = ''.join(res)
# print(res,'generrate')
# self._code = res
#
if __name__ == "__main__":
vc = VerfiyCode()
print(vc.output())
print(vc.code)
上边代码单独写一个py文件,用来生成验证码图片,使用的时候调用就行。
views视图代码:
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
#从VerifyCode文件中导入VerifyCode画验证码的类
from vcode.VerifyCode import VerfiyCode
def yzm(request):
#创建画验证码对象
vc = VerfiyCode()
#用对象调用方法
res = vc.output()
# 将验证码字符串添加到session
request.session['code'] = vc.code
return HttpResponse(res,'image/png')
def login(request):
return render(request,'app/login.html')
def dologin(request):
yzm = request.GET.get('yzm')
code = request.session.get('code')
if yzm == code:
return HttpResponse("验证成功")
return HttpResponse("验证失败")
urls代码:
from django.conf.urls import url
from vcode import views
urlpatterns = [
url(r'^yzm/$',views.yzm,name='yzm'),
url(r'^login/$',views.login,name='login'),
url(r'^dologin/$',views.dologin,name='dologin'),
]
HTML模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{width: 80px;}
</style>
</head>
<body>
<form action="{% url 'vcode:dologin' %}">
#img标签给个URL指到画验证码的视图函数,加载模板时会直接生成一个验证码图片,后边是给验证码图片加一个单击事件,更换验证码。
验证码: <input type="text" name="yzm"> <img src="{% url 'vcode:yzm' %}" onclick="this.src='{% url 'vcode:yzm' %}?'+Math.random()">
<br>
{% csrf_token %}
<input type="submit">
</form>
</body>
</html>
<script>
</script>