创建一个 Django 项目:yanzhengma 和 应用 app01
修改 urls.py 文件
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('get_valid_img.png/', views.get_valid_img),
]
在 templates 文件夹下 创建一个 login.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" action="/login/">
<fieldset>
<p>验证码: <input type="text" name="checkcode" /> <img onclick="ChangeCode();" id="imgCode" src="/get_valid_img.png" title="点击更新" /></p>
<input type="submit">
</fieldset>
</form>
<script type="text/javascript">
function ChangeCode() {
var code = document.getElementById('imgCode');
code.src += '?';
}
</script>
</body>
</html>
修改 settings.py 文件,注释下面行
# 'django.middleware.csrf.CsrfViewMiddleware',
修改 views.py 文件
from django.shortcuts import render, HttpResponse, render_to_response
from django.http import JsonResponse
from django.contrib import auth
from PIL import Image, ImageDraw, ImageFont
import io
import random
# Create your views here.
def login(request):
if request.method == 'POST':
check_code = request.POST.get('checkcode')
session_code = request.session["valid_code"]
if check_code.strip().lower() != session_code.lower():
return HttpResponse('验证码不匹配')
else:
return HttpResponse('验证码正确')
return render_to_response('login.html', {'error': ""})
def get_valid_img(request):
# 获取随机颜色的函数
def get_random_color():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
# 生成一个图片对象
img_obj = Image.new(
'RGB', # mode
(220, 35), # size
get_random_color() # color
)
# 在生成的图片上写字符
# 生成一个图片画笔对象
draw_obj = ImageDraw.Draw(img_obj)
# 加载字体文件,得到一个字体对象
font_obj = ImageFont.truetype("Monaco.ttf", 28)
tmp_list = []
for i in range(5):
u = chr(random.randint(65, 90)) # 生成大写字母
l = chr(random.randint(97, 122)) # 生成小写字母
n = str(random.randint(0, 9)) # 生成数字,要转换成字符串类型
tmp = random.choice([u, l, n])
tmp_list.append(tmp)
# draw.text():文字的绘制,第一个参数指定绘制的起始点(文本的左上角所在位置),第二个参数指定文本内容,第三个参数指定文本的颜色,第四个参数指定字体(通过ImageFont类来定义)。
draw_obj.text((20 + 40 * i, 0), tmp, fill=get_random_color(), font=font_obj)
# 保存到 session
request.session["valid_code"] = "".join(tmp_list)
# 加干扰线
width = 220 # 图片宽度(防止越界)
height = 35
for i in range(5):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
# draw.line():直线的绘制,第一个参数指定的是直线的端点坐标,形式为(x0, y0, x1, y1),第二个参数指定直线的颜色;
draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
# 加干扰点
for i in range(40):
# 在给定的坐标点上画一些点;坐标列表是包含2元组[(x,y),…]或者数字[x,y,…]的任何序列对象;变量options的fill给定点的颜色。
draw_obj.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():(椭)圆弧的绘制,第一个参数指定弧所在椭圆的外切矩形,第二、三两个参数分别是弧的起始和终止角度, 第四个参数是填充颜色,第五个参数是线条颜色;
draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color())
# 不需要在硬盘上保存文件,直接在内存中加载就可以
io_obj = io.BytesIO()
# 将生成的图片数据保存在io对象中
img_obj.save(io_obj, "png")
#从io对象里面取上一步保存的数据
data = io_obj.getvalue()
return HttpResponse(data)
生成数据库
python manage.py makemigrations
python manage.py migrate