基本设置以及结果
功能描述
规划登录注册,以及submit提交按钮
将本地加载改为网页链接动态加载
代码
<!DOCTYPE html><html lang="en">{% extends 'base.html'%}{% block content %}<head><meta charset="UTF-8"><title>登录</title><link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"></head><body><h5>登录页面</h5><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div><label for="">用户名</label><input type="text" id="user"> {# ID用于Ajax获取信息 #}</div><div><label for="">密码</label><input type="password" id="pwd"></div><input type="button" class="btn btn-default login_btn"> {# login_btn用于绑定事件 #}</form></div></div></div></body><% endblock%></html>
实现效果
第一次新增
新增描述
预期实现页面居中显示
代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>登录</title><link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"></head><body><h5>登录页面</h5><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div><label for="">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div><label for="">密码</label><input type="password" id="pwd" class="form-control"></div><input type="button" class="btn btn-default login_btn" value="submit"> {# login_btn用于绑定事件 #}</form></div></div></div></body></html>
第二次新增
设计功能: for与ID一致,可以在方框填入内容;设置submit提交按钮显示在右边
代码如下
代码
<!DOCTYPE html>{% extends 'base.html' %}{% load static %}<html lang="en">{% block content %}<head><meta charset="UTF-8"><title>登录</title></head><body><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><input type="button" class="btn btn-default login_btn pull-right" value="submit"> {# login_btn用于绑定事件 #}</form></div></div></div></body>{% endblock %}</html>
第三次新增验证码
增加验证码区域,图片区域
代码
<!DOCTYPE html>{% extends 'base.html' %}{% load static %}<html lang="en">{% block content %}<head><meta charset="UTF-8"><title>登录</title></head><body><h1>Welcome to Blog of Caesar Tylor</h1><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div><label for="pwd">验证码</label><div class="row"><div class="col-md-6"><input type="text" class="valid_code form-group"></div><div class="col-md-6"></div></div></div><input type="button" class="btn btn-default login_btn pull-right" value="submit">{# login_btn用于绑定事件 #}</form></div></div></div></body>{% endblock %}</html>
效果
第四次更改
静态生成验证码图片
代码
<!DOCTYPE html>{% extends 'base.html' %}{% load static %}<html lang="en">{% block content %}<head><meta charset="UTF-8"><title>登录</title></head><body><h1>Welcome to Blog of Caesar Tylor</h1><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div><label for="pwd">验证码</label><div class="row"><div class="col-md-6"><input type="text" class="valid_code form-group"></div><div class="col-md-6"><img width="240" height="30" src="https://tenfei05.cfp.cn/creative/vcg/800/new/VCG41N1210205351.jpg"></div></div></div><input type="button" class="pull-right btn btn-default login_btn " value="submit" >{# login_btn用于绑定事件 #}</form></div></div></div></body>{% endblock %}</html>
效果
第五次更改
逐步改进,直到动态加载验证码
import PIL
pillow官方文档 [Pillow — Pillow (PIL Fork) 8.3.1 documentation]好看的配色
(234,255,211)
1. 解决思路,前端页面使用本地连接获取图片;需要URL配置链接, 需要在view视图中负责生成相应的资源### 版本1:静态生成一个本地主项目下的图片,主要需要新引入两个包from django.shortcuts import render, HttpResponse, redirectdef login(request):return render(request, "blog/login.html")def get_validCode_img(request):with open("smooth.jpg", "rb") as f:data = f.read()return HttpResponse(data)### 版本2:生成随机颜色[磁盘存储]def get_validCode_img(request):# 第一种# with open("smooth.jpg", "rb") as f:# data = f.read()# 第二种方案def get_random_color():a = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))return aimg = Image.new("RGB", (240, 30), color=get_random_color())with open("smooth.png", "wb") as f:img.save(f, "png")with open("smooth.png", "rb") as f:data = f.read()return HttpResponse(data)### 版本3:将颜色存储在内存,并且从中读取# 第三种方案from io import BytesIOdef get_random_color():a = (random.randint(0,255), random.randint(0,255), random.randint(0,255))return aimg = Image.new("RGB", (240,30), color=get_random_color())f = BytesIO()img.save(f,"png")data=f.getvalue()return HttpResponse(data)### 版本4:生成可以验证码中的文字def get_validCode_img(request):# 第三种方案from io import BytesIOfrom PIL import Image, ImageDraw, ImageFontdef get_random_color():a = (random.randint(0,255), random.randint(0,255), random.randint(0,255))return aimg = Image.new("RGB", (240,30), color=get_random_color())draw = ImageDraw.Draw(img)kumo_font = ImageFont.truetype("static/font/kumo.ttf", 24)draw.text((0,5), "python", get_random_color(), font=kumo_font)# draw.line()# draw.point()f = BytesIO()img.save(f,"png")data=f.getvalue()return HttpResponse(data)### 版本6 : 生成随机数字def get_validCode_img(request):# 第三种方案from io import BytesIOfrom PIL import Image, ImageDraw, ImageFontdef get_random_color():a = (random.randint(0,255), random.randint(0,255), random.randint(0,255))return aimg = Image.new("RGB", (240,30), color=get_random_color())draw = ImageDraw.Draw(img)kumo_font = ImageFont.truetype("static/font/FiraCode-Regular.ttf", size=24)for i in range(5):random_num = random.randint(0,9)random_low_alpha = chr(random.randint(95, 122)) # ASCⅡ大小写字母范围random_upper_alpha = chr(random.randint(65, 90))random_char = random.choice([random_num,random_low_alpha,random_upper_alpha])draw.text((i*50 + 20,5), str(random_char), get_random_color(), font=kumo_font) # 转换第二个参数的类型f = BytesIO()img.save(f,"png")data=f.getvalue()return HttpResponse(data)### 版本7:增加噪点和噪线,增加机器识别难度def get_validCode_img(request):from io import BytesIOfrom PIL import Image, ImageDraw, ImageFontdef get_random_color():a = (random.randint(0,255), random.randint(0,255), random.randint(0,255))return aimg = Image.new("RGB", (240,30), color=get_random_color())draw = ImageDraw.Draw(img)kumo_font = ImageFont.truetype("static/font/FiraCode-Regular.ttf", size=24)for i in range(5):random_num = random.randint(0,9)random_low_alpha = chr(random.randint(95, 122)) # ASCⅡ大小写字母范围random_upper_alpha = chr(random.randint(65, 90))random_char = random.choice([random_num,random_low_alpha,random_upper_alpha])draw.text((i*50 + 20,5), str(random_char), get_random_color(), font=kumo_font) # 转换第二个参数的类型width = 250height = 40for i in range(10):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, x2, y1, y2), fill=get_random_color())for i in range(200):draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())f = BytesIO()img.save(f,"png")data=f.getvalue()return HttpResponse(data)
第六次设置点击自动刷新验证码
实现逻辑分析
1. 引入Jquery文件2. 登录源码中绑定事件,实现点击自动刷新
关联配置信息
### H5中的配置,修改第32行代码,增加ID,末尾使用script标签加载Jquery<!DOCTYPE html>{% extends 'base.html' %}{% load static %}<html lang="en">{% block content %}<head><meta charset="UTF-8"><title>登录</title></head><body><h1>Welcome to Blog of Caesar Tylor</h1><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div><label for="pwd">验证码</label><div class="row"><div class="col-md-6"><input type="text" class="valid_code form-group"></div><div class="col-md-6"><img width="240" height="30" id="valid_code_img" src="/get_validCode_img/" alt=""></div></div></div><input type="button" class="pull-right btn btn-default login_btn " value="submit" >{# login_btn用于绑定事件 #}</form></div></div></div><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>{# <script src="C:/Users/41999/Documents/projectmanagement/Test/Scripts/whereabouts/static/js/jquery-3.6.0.min.js"></script>#}</body>{% endblock %}</html>### browser调试代码$("#valid_code_img")[0]<img width="240" height="30" id="valid_code_img" src="/get_validCode_img/" alt>$("#valid_code_img")[0].src+="?""http://127.0.0.1:8001/get_validCode_img/?"$("#valid_code_img")[0].src+="??""http://127.0.0.1:8001/get_validCode_img/???"$("#valid_code_img")[0].src+="??""http://127.0.0.1:8001/get_validCode_img/?????"
网页调试过程
第七次 升级配置
保存原有配置
<!DOCTYPE html>{% extends 'base.html' %}{% load static %}<html lang="en">{% block content %}<head><meta charset="UTF-8"><title>登录</title></head><body><h1>Welcome to Blog of Caesar Tylor</h1><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div><label for="pwd">验证码</label><div class="row"><div class="col-md-6"><input type="text" class="valid_code form-group"></div><div class="col-md-6"><img width="240" height="30" id="valid_code_img" src="/get_validCode_img/" alt=""></div></div></div><input type="button" class="pull-right btn btn-default login_btn " value="submit" >{# login_btn用于绑定事件 #}</form></div></div></div>{# <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>#}<script src="{% static '/static/js/jquery-3.6.0.min.js' %}"></script><script>// 验证码图片刷新$("#valid_code_img").click(function(){$("this")[0].src+="?"})</script></body>{% endblock %}</html>
升级后的配置
<!DOCTYPE html>{% load static %}<html lang="en"><head><meta charset="UTF-8"><title>登录</title><link rel="stylesheet" href="{% static '/static/blog/bs/css/bootstrap.css' %}"></head><body><h1>Welcome to Blog of Caesar Tylor</h1><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div><label for="pwd">验证码</label><div class="row"><div class="col-md-6"><input type="text" class="valid_code form-group"></div><div class="col-md-6"><img width="240" height="30" id="valid_code_img" src="/get_validCode_img/" alt=""></div></div></div><input type="button" class="pull-right btn btn-default login_btn " value="submit" >{# login_btn用于绑定事件 #}</form></div></div></div><script src="{% static '/static/js/jquery-3.6.0.min.js' %}"></script><script>$("#valid_code_img").click(function(){$(this)[0].src+="?"})</script></body></html>
二者区别
不再使用基文件和模板标签,直接使用资源引用中的静态文件模板标签,加载的内容减少了
第八次修改—-增加保存验证码的功能
后端支持代码
from django.shortcuts import render, HttpResponse, redirectimport PIL, randomfrom django.http import JsonResponsefrom django.contrib import authdef login(request):"""auth.login:在请求中保留用户id和后端。这样,用户就不必在每次请求时都重新验证。请注意,匿名会话期间的数据集在用户登录时保留。auth.authenticate: 从client请求中提取数据,将数据与数据库进行匹配response: 用一个字典作为message传递提示信息"""if request.method=="POST":response = {"user":None,"msg":None}user = request.POST.get("user")print(user)pwd = request.POST.get("pwd")valid_code_one = request.POST.get("valid_code")valid_code = str(valid_code_one)valid_code_str = request.session.get("valid_code_str")# print(valid_code) 测试后端在提交前端显示之前保存的验证码# print(valid_code_str) 测试前端POST请求提交时给出的验证码if valid_code.upper() == valid_code_str.upper():user=auth.authenticate(username=user,password=pwd) # 将前端提交的密码与后端MySQL存储的用户名与密码匹配if user:auth.login(request,user) # 匹配成功后则将其注册request.user==当前登录对象,存储当前登录对象response["user"]=user.usernameelse:response["msg"]="username or password error!"else:response["msg"] = "valide code error!"return JsonResponse(response)return render(request, "blog/login.html")def get_validCode_img(request):from io import BytesIOfrom PIL import Image, ImageDraw, ImageFontdef get_random_color():a = (random.randint(0,255), random.randint(0,255), random.randint(0,255))return aimg = Image.new("RGB", (240,30), color=get_random_color())draw = ImageDraw.Draw(img)kumo_font = ImageFont.truetype("static/font/FiraCode-Regular.ttf", size=24)valid_code_str = ""for i in range(5):random_num = random.randint(0,9)random_low_alpha = chr(random.randint(95, 122)) # ASCⅡ大小写字母范围random_upper_alpha = chr(random.randint(65, 90))random_char = random.choice([random_num,random_low_alpha,random_upper_alpha])draw.text((i*50 + 20,5), str(random_char), get_random_color(), font=kumo_font) # 转换第二个参数的类型# 保存验证码字符串valid_code_str+=str(random_char)width = 250height = 40for i in range(10):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, x2, y1, y2), fill=get_random_color())for i in range(200):draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())# 打印保存的验证码# print("valid_code_str", valid_code_str)request.session["valid_code_str"]=valid_code_str"""1. 生成随机字符串2. 设置一个cookie{sessionid:随机字符串}3. django——session存储session_key---随机字符串,session_data---验证码"""f = BytesIO()img.save(f,"png")data=f.getvalue()# print(type(data))return HttpResponse(data)def index(request):return render(request, "blog/index.html")
保存环境
from django.shortcuts import render, HttpResponse, redirectimport PIL, randomdef login(request):return render(request, "blog/login.html")def get_validCode_img(request):from io import BytesIOfrom PIL import Image, ImageDraw, ImageFontdef get_random_color():a = (random.randint(0,255), random.randint(0,255), random.randint(0,255))return aimg = Image.new("RGB", (240,30), color=get_random_color())draw = ImageDraw.Draw(img)kumo_font = ImageFont.truetype("static/font/FiraCode-Regular.ttf", size=24)valid_code_str = ""for i in range(5):random_num = random.randint(0,9)random_low_alpha = chr(random.randint(95, 122)) # ASCⅡ大小写字母范围random_upper_alpha = chr(random.randint(65, 90))random_char = random.choice([random_num,random_low_alpha,random_upper_alpha])draw.text((i*50 + 20,5), str(random_char), get_random_color(), font=kumo_font) # 转换第二个参数的类型width = 250height = 40for i in range(10):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, x2, y1, y2), fill=get_random_color())for i in range(200):draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())f = BytesIO()img.save(f,"png")data=f.getvalue()return HttpResponse(data)
修改后的代码
<!DOCTYPE html>{% load static %}<html lang="en"><head><meta charset="UTF-8"><title>登录</title><link rel="stylesheet" href="{% static '/static/blog/bs/css/bootstrap.css' %}"></head><body><h1>Welcome to Blog of Caesar Tylor</h1><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}{% csrf_token %} {# 增加CSRF防护令牌 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div class="form-group">{# for写错了 #}<label for="pwd">验证码</label><div class="row"><div class="col-md-6">{# ID和class写到一起了 #}<input type="text" class="form-control" id="valid_code"></div><div class="col-md-6"><img width="240" height="30" id="valid_code_img" src="/get_validCode_img/" alt=""></div></div></div><input type="button" class="btn btn-default login_btn pull-right" value="submit" >{# login_btn用于绑定事件 #}</form></div></div></div><script src="{% static '/static/js/jquery-3.6.0.min.js' %}"></script><script>// 点击刷新验证码$("#valid_code_img").click(function(){$(this)[0].src+="?"});// 登录验证$(".login_btn").click(function(){$.ajax({url:"",type:"post",data:{user:$("#user").val(),pwd:$("#pwd").val(),valid_code:$("#valid_code").val(),csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),},success:function(data){console.log(data);}})})</script></body></html>
修改过程
1. 构建Ajax事件,传递参数1. 设计传递参数的内容,分别为用户,密码,验证码,csrf_token令牌2. csrf_token令牌由模板标签产生,在浏览器前台源码中获得H5名称2. 构建登录页面的重定向(在login.h5页面内)1. 接收Ajax提交的数据,首先校验验证码[但不能将验证码改为全局变量直接校验,易在并发过程中被存储的其他用户的验证码覆盖]2. 使用cookie和session会话技术3. from django.http import JsonResponse,自动构建序列化,Ajax直接拿数据,无需反序列化4. 逐次校验数据3. 测试并且提交用户1. 使用Ajax原地跳转并且提示错误信息2. y
前台测试—验证码错误和验证码为空状态下的错误信息提示
MySQL中会话记录的查看
数据库表中存储的用户信息
测试用户信息提交
Ajax部分代码备份
// 登录验证$(".login_btn").click(function(){$.ajax({url:"",type:"post",data:{user:$("#user").val(),pwd:$("#pwd").val(),valid_code:$("#valid_code").val(),csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),},success:function(data){console.log(data);if(data.user){location.href="/index/"}else{$(".error").text(data.msg).css({"color":"red","margin-left":"10px"});}}})})
第九次修改—验证码代码优化
增加提示语自动消失的功能
<script>// 点击刷新验证码$("#valid_code_img").click(function(){$(this)[0].src+="?"});// 登录验证$(".login_btn").click(function(){$.ajax({url:"",type:"post",data:{user:$("#user").val(),pwd:$("#pwd").val(),valid_code:$("#valid_code").val(),csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),},success:function(data){// 将会在控制台打印log信息,据此可以判断获取信息是否全面准确console.log(data);if(data.user){location.href="/index/";{#window.location="index.html";#}}// 使得验证码错误的提示信息在一秒钟之后消失else{$(".error").text(data.msg).css({"color":"red","margin-left":"10px"});setTimeout(function(){$(".error").text("")},1000)}}})})</script>
极验滑动验证码的嵌入
1. 包准备social-auth-app-django==5.0.0social-auth-core==4.1.0
功能解耦
在blog下新建
utlis文件夹,额外创建__init__.py文件夹将随机数生成和验证码生成的功能独立解耦
view.py文件
def get_validCode_img(request):from blog.utils.validCode import get_valide_code_imgdata = get_valide_code_img(request)# print(type(data))return HttpResponse(data)
前端login.html文件
<!DOCTYPE html>{% load static %}<html lang="en"><head><meta charset="UTF-8"><title>登录</title><link rel="stylesheet" href="{% static '/static/blog/bs/css/bootstrap.css' %}"><link rel="shortcut icon" href="{% static 'static/blog/img/favicon.ico' %}" type="image/x-icon"></head><body><h3>Welcome to Blog of Caesar Tylor</h3><div class="container"><div class="row"><div class="col-md-6 col-lg-offset-3"> {# 占用六个,右倾 #}<form> {# action不再定义,基于Ajax提交 #}{% csrf_token %} {# 增加CSRF防护令牌 #}<div class="form-group"><label for="user">用户名</label><input type="text" id="user" class="form-control"> {# ID用于Ajax获取信息 #}</div><div class="form-group"><label for="pwd">密码</label><input type="password" id="pwd" class="form-control"></div><div class="form-group"><label for="pwd">验证码</label><div class="row"><div class="col-md-6"><input type="text" class="form-control" id="valid_code"></div><div class="col-md-6"><img width="240" height="30" id="valid_code_img" src="/get_validCode_img/" alt=""></div></div></div><input type="button" class="btn btn-default login_btn" value="submit" ><span class="error"></span>{# login_btn用于绑定事件 #}<a href="/registry/" class="btn btn-success pull-right">注册</a></form></div></div></div><script src="{% static '/static/js/jquery-3.6.0.min.js' %}"></script><script>// 点击刷新验证码$("#valid_code_img").click(function(){$(this)[0].src+="?"});// 登录验证$(".login_btn").click(function(){$.ajax({url:"",type:"post",data:{user:$("#user").val(),pwd:$("#pwd").val(),valid_code:$("#valid_code").val(),csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),},success:function(data){// 将会在控制台打印log信息,据此可以判断获取信息是否全面准确console.log(data);if(data.user){location.href="/index/";{#window.location="index.html";#}}// 使得验证码错误的提示信息在一秒钟之后消失else{$(".error").text(data.msg).css({"color":"red","margin-left":"10px"});setTimeout(function(){$(".error").text("")},1000)}}})})</script></body></html>
valideCode.py
# -*- coding: utf-8 -*-# @Time : 2021/8/25 9:53# @Author : 41999# @Email : 419997284@qq.com# @File : validCode.py# @Project : whereaboutsfrom io import BytesIOfrom PIL import Image, ImageDraw, ImageFontimport randomdef get_random_color():a = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))return adef get_valide_code_img(request):img = Image.new("RGB", (240, 30), color=get_random_color())draw = ImageDraw.Draw(img)kumo_font = ImageFont.truetype("static/font/FiraCode-Regular.ttf", size=24)valid_code_str = ""for i in range(5):random_num = random.randint(0, 9)random_low_alpha = chr(random.randint(95, 122)) # ASCⅡ大小写字母范围random_upper_alpha = chr(random.randint(65, 90))random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])draw.text((i * 50 + 20, 5), str(random_char), get_random_color(), font=kumo_font) # 转换第二个参数的类型# 保存验证码字符串valid_code_str += str(random_char)width = 250height = 40for i in range(10):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, x2, y1, y2), fill=get_random_color())for i in range(200):draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())# 打印保存的验证码# print("valid_code_str", valid_code_str)request.session["valid_code_str"] = valid_code_str"""1. 生成随机字符串2. 设置一个cookie{sessionid:随机字符串}3. django——session存储session_key---随机字符串,session_data---验证码"""f = BytesIO()img.save(f, "png")data = f.getvalue()return data
