Django 使用图片验证码进行登录
程序员文章站
2022-03-12 22:29:58
Day 20/12/30图片验证码登录生成图片验证码pip install pillow# -*- coding = utf-8 -*-# @Time : 2020/12/29 16:09# @Author : Chenih# @File : image_code.py# @Software : PyCharmfrom PIL import Image, ImageDraw, ImageFilter, ImageFontimport random"""绘制图片验证码"""...
Day 20/12/30
图片验证码登录
生成图片验证码
pip install pillow
# -*- coding = utf-8 -*-
# @Time : 2020/12/29 16:09
# @Author : Chenih
# @File : image_code.py
# @Software : PyCharm
from PIL import Image, ImageDraw, ImageFilter, ImageFont
import random
"""绘制图片验证码"""
def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
code = []
img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')
def rndChar():
"""
生成随机字母
:return:
"""
return chr(random.randint(65, 90))
def rndColor():
"""
生成随机颜色
:return:
"""
return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
# 写文字
font = ImageFont.truetype(font_file, font_size)
for i in range(char_length):
char = rndChar()
code.append(char)
h = random.randint(0, 4)
draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
# 写干扰点
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
# 写干扰圆圈
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
# 画干扰线
for i in range(5):
x1 = random.randint(0, width)
y1 = random.randint(0, height)
x2 = random.randint(0, width)
y2 = random.randint(0, height)
draw.line((x1, y1, x2, y2), fill=rndColor())
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
return img, ''.join(code)
if __name__ == '__main__':
image_obj, code = check_code()
image_obj.show() # 直接打开
# 2. 写入文件
# img,code = check_code()
# with open('code.png','wb') as f:
# img.save(f,format='png')
# 3. 写入内存
# from io import BytesIO
# stream = BytesIO()
# img.save(stream, 'png')
# stream.getvalue()
图片验证码路由
path('image/code/', account.image_code, name='image_code')
验证码图片的视图函数
def image_code(request):
"""生成图片验证码"""
# 调用函数生成图片验证码
image_obj, code = check_code()
# 将验证码字符存入session
request.session['code'] = code
request.session.set_expiry(60)
# 创建一个内存空间
stream = BytesIO()
# 将生成的图片验证码保存在内存空间中
image_obj.save(stream, 'png')
# 将从内存空间获取的图片验证码传给前端
return HttpResponse(stream.getvalue())
页面显示
{% extends 'layout/basic.html' %}
{% load static %}
{% block title %} 邮箱|手机号 登录 {% endblock %}
{% block css %}
<link rel="stylesheet" href="{% static 'css/account.css' %}">
<style>
.error-msg {
color: red;
position: absolute;
font-size: 13px;
}
</style>
{% endblock %}
{% block content %}
<div class="account">
<div class="title">邮箱|手机号 登录</div>
<form id="smsForm" method="POST" novalidate>
{% csrf_token %}
{% for field in form %}
{% if field.name == 'code' %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
<div class="row">
<div class="col-xs-7">
{{ field }}
<span class="error-msg">{{ field.errors.0 }}</span>
</div>
<div class="col-xs-5">
{# 从image_code中拿到生成的图片 #}
<img src="{% url 'image_code' %}" id="imageCode" title="点击更换图片" alt="">
</div>
</div>
</div>
{% else %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<span class="error-msg">{{ field.errors.0 }}</span>
</div>
{% endif %}
{% endfor %}
<div>
<div style="float: right">
<a href="{% url 'loginsms' %}">短信验证码登录?</a>
</div>
</div>
<div class="row">
<div class="col-xs-3">
<input type="submit" class="btn btn-primary" value="登 录"/>
</div>
</div>
</form>
</div>
{% endblock %}
{% block js %}
<script>
$(function () {
$('#imageCode').click(function () {
var oldSrc = $(this).attr('src');
$(this).attr('src', oldSrc + '?');
})
})
</script>
{% endblock %}
验证码图片的点击更换:
给图片<img src="{% url 'image_code' %}" id="imageCode" title="点击更换图片" alt="">设置id,平且给此id添加点击事件。
{% block js %}
<script>
$(function () {
// 找到id为imageCode,添加点击事件
$('#imageCode').click(function () {
// 定义变量oldSrc,拿到当前id的src属性的值(图片地址)
var oldSrc = $(this).attr('src');
// 每点击一次就将当前id所在的src的值加一个?(用来替换图片)
// oldSrc -> oldSrc? -> oldSrc?? -> ...
$(this).attr('src', oldSrc + '?');
})
})
</script>
{% endblock %}
登录
def login(request):
"""用户名密码登录"""
if request.method == 'GET':
form = LoginForm(request)
return render(request, 'login.html', {'form': form})
form = LoginForm(request, data=request.POST)
if form.is_valid():
# 获取数据时写的name为username,实际上获取的是手机号或者邮箱
username = form.cleaned_data['username']
password = form.cleaned_data['password']
# user_obj = models.User.objects.filter(username=username, password=password).first()
# 使用Q对象构造复杂的查询对象(判断是用email还是phone登录的)
user_obj = models.User.objects.filter(Q(email=username) | Q(phone=username)).filter(password=password).first()
if user_obj:
# 如果此用户存在,那么将用户的id保存在session中
request.session['user_id'] = user_obj.pk
request.session.set_expiry(60*60*24*14)
return redirect('index')
# 若不存在此用户,则抛出错误提示
form.add_error('username', '用户名或密码有误')
return render(request, 'login.html', {'form': form})
本文地址:https://blog.csdn.net/weixin_43670190/article/details/111964614
上一篇: 上海有什么特产小吃可以带回家
下一篇: 太史慈为什么没有位列江东十二虎臣?