登陆功能
目录
本功能需求:
-使用Ajax提交数据信息
-渲染用户名密码不符合要求的错误信息
-登陆后可以实现登出当前账号
拓展需求:
-登陆时判断用户是否被冻结
-登陆时使用登陆表单进行验证
一、添加路由
在urls.py中添加
1、登陆路由
path('login/', views.login, name='login'),
2、生成随机验证码路由
path('get_valid_code/', views.get_valid_code, name='get_valid'),
3、登出当前用户路由
path('logout/', views.logout, name='logout'),
二、添加视图函数
在views.py中
1、先导入一些需要的模块
from django.contrib import auth
from django.contrib.auth import authenticate
其中涉及到一个手动添加登录验证码的操作
添加视图函数get_rgb(随机函数,利用RGB形成随机颜色)
和get_valid_code(获取随机验证码)
def get_rgb():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
def get_valid_code(request):
img = Image.new('RGB', (200, 38), get_rgb())
img_draw = ImageDraw.Draw(img)
img_font = ImageFont.truetype('./static/font/FZFenSTXJW.TTF', 25)
valid_code = ''
for i in range(5):
low_char = chr(random.randint(97, 122))
num_char = random.randint(0, 9)
upper_char = chr(random.randint(65, 90))
res = random.choice([low_char, num_char, upper_char])
valid_code += str(res)
img_draw.text((i * 40 + 10, 5), str(res), get_rgb(), img_font)
request.session['valid_code'] = valid_code
print(valid_code)
f = BytesIO()
img.save(f, 'png')
data = f.getvalue()
return HttpResponse(data)
随机验证码
"""
图片相关的模块
pip3 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):
# 最终步骤4:写图片验证码
img_obj = Image.new('RGB', (430, 35), get_random())
img_draw = ImageDraw.Draw(img_obj) # 产生一个画笔对象
img_font = ImageFont.truetype('static/font/222.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_lower,random_upper,random_int])
# 将产生的随机字符串写入到图片上
"""
为什么一个个写而不是生成好了之后再写
因为一个个写能够控制每个字体的间隙 而生成好之后再写的话
间隙就没法控制了
"""
img_draw.text((i*60+60,-2),tmp,get_random(),img_font)
# 拼接随机字符串
code += tmp
print(code)
# 随机验证码在登陆的视图函数里面需要用到 要比对 所以要找地方存起来并且其他视图函数也能拿到
request.session['code'] = code
io_obj = BytesIO()
img_obj.save(io_obj,'png')
return HttpResponse(io_obj.getvalue())
2、登录功能视图函数
def login(request):
if request.method == 'POST':
# 1.返回数据格式
back_dic = {'code':200, 'msg': '登录成功'}
# 2.接收参数
username = request.POST.get('username')
password = request.POST.get('password')
code = request.POST.get('code')
# 3.验证参数
if request.session.get('code').lower() != code.lower():
back_dic['code'] = 1003
back_dic['msg'] = '验证码不正确'
return JsonResponse(back_dic)
# 4.处理业务逻辑
new_pwd = my_hashlib(password)
user_obj = models.UserInfo.objects.filter(username=username, password=new_pwd).first() # 第一个错误 小心这里
if not user_obj:
back_dic['code'] = 1004
back_dic['msg'] = '用户名或者密码错误'
return JsonResponse(back_dic)
print(user_obj)
# 登录成功,保存用户状态
request.session['username'] = user_obj.username
print(2)
request.session['id'] = user_obj.pk
back_dic['url'] = '/home/'
return JsonResponse(back_dic)
return render(request, 'login.html')
3、login.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.css">
<script src="/static/bootstrap-3.4.1-dist/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center">登录页面</h1>
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" class="form-control">
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" class="form-control">
</div>
<div class="form-group">
<label for="code">验证码:</label>
<div class="row">
<div class="col-md-6">
<input type="text" id="code" class="form-control">
</div>
<div class="col-md-6">
<img src="/get_code/" alt="" id="img_code" style="width: 343px;height: 52px;}">
</div>
</div>
<div>
<input type="botton" class="btn btn-primary btn-block" value="登录">
</div>
</div>
</div>
</div>
<script src="/static/layer/layer.js"></script>
<script>
$("#img_code").click(function () {
var old_src = $(this).attr('src');
$(this).attr('src', old_src += '?');
});
$('.btn').click(function () {
var username = $('#username').val();
var password = $('#password').val();
var code = $('#code').val();
// 2.参数验证
if (!username) {
layer.msg('用户名必须填写!')
return
}
var obj = {username: username, password: password, code: code, csrfmiddlewaretoken: '{{ csrf_token }}'}
// 3.把参数提交到后端,发起Ajax请求
$.ajax({
url: '',
type: 'post',
data: obj,
success: function (res) {
if (res, code == 200) {
layer.msg(res.msg, {}, function () {
location.href = res.url;
})
} else {
layer.msg(res.msg);
}
}
})
})
</script>
</body>
</html>
找字体网站:https://www.zhaozi.cn/s/all/ttf/
在HTML中,img标签的src属性可以指定以下几种值:
绝对路径URL:
例如,。这指定了一个完整的URL地址,它可以是在同一个网站的页面上,也可以是不同网站上的图片。特点是易于使用和理解,但在某些情况下可能会导致页面加载速度变慢。
相对路径URL:
例如,。这指定了相对于当前HTML文件的路径。特点是在同一个网站内移动页面时更方便,但如果文件结构发生更改,则需要相应地更新相对路径。
Base64编码(Data URL):
例如,。这是一种将图片编码为Base64字符串并将其嵌入到HTML文档中的方法。特点是可以在页面上减少HTTP请求的数量,但是会增加HTML文件的大小。
Blob URL:
例如,。这是一种将图片作为Blob对象URL嵌入到HTML文档中的方法。特点是可以在客户端直接处理图片,而无需向服务器发送请求,但这也会增加HTML文件的大小。
空字符串:
例如,。这是一种将图像元素添加到HTML文档中但不加载实际图像的方法,可以用于在文档中保留图像元素的占位符。