Django之验证码的实现,简单快捷的方法

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 = 100
    height = 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秒再输入验证码是不会成功的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值