后端
url.py
# 图片验证码相关
path('get_code/', views.get_code, name='gc'),
根据这条url获取随机验证码
·····································
"""
图片相关的模块
pip install pillow
"""
from PIL import Image, ImageDraw, ImageFont
"""
Image:生成图片
ImageDraw:能在图片上乱写乱画
ImageFont: 控制字体样式
"""
from io import BytesIO, StringIO
"""
内存管理器模块
BytesIO 临时存储数据,返回的是二进制格式
StringIO 临时存储数据,返回的是字符串格式
"""
import random
# 获得随机整数,从而得到随机的颜色
def get_random():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
# 将验证码画在图片上,传给前端
def get_code(request):
# 推导步骤1 : 直接获取后端现成的图片二进制数据发送给前端
# with open(r'static\img\111.jpg', 'rb') as f:
# data = f.read()
# return HttpResponse(data)
# 推导步骤2: 利用pillow模块,动态产生图片
# img_obj = Image.new('RGB', (430, 35), 'green')
# img_obj = Image.new('RGB', (430, 35), get_random()) # 基于图片的三基色
# # 先将图片对象保存起来,
# with open('xxx.png', 'wb') as f:
# img_obj.save(f, 'png') # 文件句柄,图片格式
# # 再将图片对象读取出来
# with open('xxx.png', 'rb') as f:
# data = f.read()
# return HttpResponse(data)
# 推导步骤3: 文件存储繁琐 IO操作效率低
# img_obj = Image.new('RGB', (430, 35), get_random())
# io_obj = BytesIO() # 生成一个内存管理器对象,可以看成是文件句柄
# img_obj.save(io_obj, 'png') # 指定图片的格式
# return HttpResponse(io_obj.getvalue()) # 从内存管理器中读取图片的二进制数据,返回给前端
# 最终步骤4: 写图片验证码
img_obj = Image.new('RGB', (430, 35), get_random()) # 格式,位置,内容
img_draw = ImageDraw.Draw(img_obj) # 产生一个画笔对象
img_font = ImageFont.truetype('static/font/111.ttf', 30) # 字体样式,大小
# 随机验证码 五位数的随机验证码 (数字 小写字母 大写字母)
code = ''
for i in range(5):
random_upper = chr(random.randint(65, 90))
random_lower = chr(random.randint(97, 122))
random_int = str(random.randint(0, 9))
# 从上面三个里面随机选择一个
tmp = random.choice([random_int, random_upper, random_lower])
# 将产生的随机字符串写入到图片上(为了五个字符之间有距离,所以一个一个往里面写)
img_draw.text((i * 50 + 60, -2), tmp, get_random(), img_font)
# 拼接随机字符串
code += tmp
print(code)
# 随机验证码 在登录的视图函数里面要用到,要对比,所以可以存到session里面
request.session['code'] = code
io_obj = BytesIO()
img_obj.save(io_obj, 'png') # 将图片对象保存到内存管理器,并指定格式
return HttpResponse(io_obj.getvalue())
前端
<div class="form-group">
<label for="">验证码</label>
<div class="row">
<div class="col-md-6">
<input type="text" name="id_code" id="id_code" class="form-control">
</div>
<div class="col-md-6">
<img src="/get_code/" alt="" width="430" height="35" id="id_img">
</div>
</div>
</div>
<script>
//实现验证码图片的点击更新
$('#id_img').click(function () {
// 1 先获取标签的src
let oldVal = $(this).attr('src')
$(this).attr('src', oldVal += '?') //src 变换一次,就朝后端发送一个ajax请求。
})
//朝后端发送ajax请求
$('#id_commit').click(function () {
$.ajax({
url: '',
type: 'post',
data: {
'username': $('#username').val(),
'password': $('#password').val(),
'code': $('#id_code').val(),
// csrf 集合自己需求 合理选择
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success:function (args){
console.log(args)
if (args.code==1000){
// 登录成功,跳转首页
window.location.href = args.url
}else{
//渲染错误信息
$('#error').text(args.msg)
}
}
})
})
</script>