前言:目前还在学习中,这是第一个尝试的项目,多有不足,感谢大家的观看与批评。
目标:
一. 创建纯净版django项目
python = 3.10,不作赘述
二. 网页界面制作
直接去网站Bootstrap 3 Login Examples找一个长得差不多的
这里选择第二个,点击进入后直接复制需要的部分,稍作调整
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>用户登录</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<style>
.container {
width: 450px;
margin-top: 100px;
box-shadow: 5px 5px 25px rgba(0, 0, 0, 0.1);
}
.col-lg-12 {
padding: 15px;
}
</style>
</head>
<body>
<div class="container">
<div class="col-lg-12">
<h1 class="text-center">用户登录</h1>
<form id="login-form" method="post" role="form" style="display: block;">
<h4>用户类型</h4>
<select id="selectbasic" name="selectbasic" class="form-control">
<option value="1">客户</option>
<option value="2">管理员</option>
</select>
<h4>用户名</h4>
<div class="form-group">
<input type="text" name="password" id="password" tabindex="2" class="form-control"
placeholder="请输入用户名">
</div>
<h4>密码</h4>
<div class="form-group">
<input type="password" name="password" id="password" tabindex="2" class="form-control"
placeholder="请输入密码">
</div>
<h4>图片验证码</h4>
<div class="form-group">
<input type="text" name="password" id="password" tabindex="2" class="form-control"
placeholder="请输入图片验证码">
</div>
</form>
<a href="#" class="btn btn-primary btn-default">登陆</a>
</div>
</div>
</body>
</html>
效果:
图片验证码
参考的这位前辈的文章:登录界面中图片验证码的生成和校验_图片登录校验-CSDN博客
注意点:
1. 前文提到创建的纯净版项目,所以要提前将session解除注释
2. 将最后一个 .form-control 单独修改为 inline-block,不然图片不能在一行内显示。
3. 前辈说的字体下载后加载时遇到了一点问题,我修改成了电脑默认字体`arial.ttf`
完成后效果:
三. 功能制作
使用`forms`组件
class LoginForm(forms.Form):
TYPE_CHOICES = (
('1', '客户'),
('2', '管理员'),
)
type = forms.ChoiceField(
choices=TYPE_CHOICES,
widget=forms.Select(attrs={'class': 'form-control'}),
label='用户类型'
)
name = forms.CharField(
required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': "请输入用户名"}),
min_length=1,
max_length=13,
error_messages={"required": "该字段不能为空"},
label='用户名'
)
pwd = forms.CharField(
required=True,
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': "请输入密码"}),
error_messages={"required": "该字段不能为空"},
label='密码'
)
img_code = forms.CharField(
required=True,
widget=forms.TextInput(attrs={'class': 'form-control img-code', 'placeholder': "请输入图片验证码"}),
label='图片验证码'
)
`models.py`:
from django.db import models
class User(models.Model):
type = models.CharField(max_length=32, verbose_name='用户类型')
name = models.CharField(max_length=32, verbose_name='用户名')
pwd = models.CharField(max_length=64, verbose_name='密码')
img_code = models.CharField(max_length=64, verbose_name='图片验证码')
修改前端代码:
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>用户登录</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<style>
.container {
width: 450px;
margin-top: 100px;
box-shadow: 5px 5px 25px rgba(0, 0, 0, 0.1);
}
.col-lg-12 {
padding: 15px;
}
.img-code {
width: 50%;
margin-right: 35px;
}
.form-control {
display: inline-block;
}
</style>
</head>
<body>
<div class="container">
<div class="col-lg-12">
<h1 class="text-center">用户登录</h1>
<form id="login-form" method="post" role="form" style="display: block;" novalidate>
{% csrf_token %}
<h4>用户类型</h4>
{{ form.type }}
<h4>用户名</h4>
<div class="form-group">
{{ form.name }}
</div>
<h4>密码</h4>
<div class="form-group">
{{ form.pwd }}
</div>
<h4>图片验证码</h4>
<div class="form-group">
{{ form.img_code }}
<div class="img-code" style="display: inline"><a href="/login/"><img id="image_code"
src="/image/code/"></a></div>
<span class="error_massage">{{ form.img_code.errors }}</span>
</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>
</div>
</html>
注意点:
`{% csrf_token %}`、`<button>`要放在<form>里面。
最后就是`login`函数的编写:
def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, "base_html/login.html", {"form": form})
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
# 获取表单数据
# 获取后删除图片验证码
input_code = form.cleaned_data.pop('img_code')
user_type = form.cleaned_data['type'] # 客户:1;管理员:2
name = form.cleaned_data['name']
password = form.cleaned_data['pwd']
# 优先验证图片验证码
real_code = request.session.get('image_code')
if real_code is not None:
if real_code.upper() != input_code.upper():
form.add_error("img_code", "验证码错误")
return render(request, "base_html/login.html", {"form": form})
else:
return render(request, "base_html/login.html", {"form": form})
# 验证用户数据
try:
user = User.objects.get(type=user_type, name=name, pwd=password)
# 验证成功,可以执行其他操作
user_type = int(user_type)
if user_type == 1:
return HttpResponse("客户登陆成功")
else:
return HttpResponse("管理员登陆成功")
except User.DoesNotExist:
# 验证失败,返回错误信息
form.add_error("img_code", "登录失败,用户类型、用户名或密码不正确")
return render(request, "base_html/login.html", {"form": form})
else:
form = LoginForm()
return render(request, 'base_html/login.html', {'form': form})
注意点:
user_type的值:1、2是字符串类型的值,要转换为int类型
四. 细节补充
1. 回复错误时的字体修改:
修改前:
添加代码:
.error_massage ul{
margin-top: 10px;
margin-bottom: 0;
padding-left: 0;
}
.error_massage li{
color: red;
list-style-type: none;
}
修改后:
2. 点击验证码刷新功能
这里使用`jQuery`:
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
$(document).ready(function () {
$("#image_code").on("click", function (event) {
event.preventDefault(); // 防止链接的默认行为
refreshCaptcha();
});
function refreshCaptcha() {
// 使用 AJAX 获取新的验证码图像,而无需刷新整个页面
$.ajax({
url: "/image/code/",
method: "GET",
success: function (data) {
// 用新的验证码 URL 更新图片的 src 属性
$("#image_code").attr("src", "/image/code/");
},
error: function (error) {
console.error("Error refreshing captcha:", error);
}
});
}
});
</script>
此时点击验证码能够刷新并且不修改用户已填写的数据。