【Django】教程-1-安装+创建项目+目录结构介绍
【Django】教程-2-前端-目录结构介绍
【Django】教程-3-数据库相关介绍
【Django】教程-4-一个增删改查的Demo
【Django】教程-5-ModelForm增删改查+规则校验【正则+钩子函数】
【Django】教程-6-搜索框-条件查询前后端
【Django】教程-7-分页,默认使用django的
【Django】教程-8-页面时间组件
【Django】教程-9-登录+退出
【Django】教程-10-ajax请求Demo,结合使用
【Django】教程-11-ajax弹窗实现增删改查
【Django】教程-12-柱状图
【Django】教程-13-饼图,折线图
【Django】教程-14-验证码+登录页
20. 注册页
重新写一个注册的ModelForm就可快速实现
forms.py
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator, EmailValidator
from . import models
from .models import Department, UserInfo, Admin, Order
from .util.md5 import md5
class BootstrapModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环Modelform中所有字段,给每个字段插件设置
for name, field in self.fields.items():
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
def as_div(self):
"""
自定义表单渲染方法,将错误信息显示在字段下方并设置为红色
"""
output = []
for bound_field in self:
label_html = f'<label for="{bound_field.id_for_label}">{bound_field.label}</label>'
field_html = f'<div class="form-group">{label_html}{bound_field}</div>'
if bound_field.errors:
error_html = ''.join([f'<span class="text-danger">{error}</span>' for error in bound_field.errors])
field_html += f'<div class="error-message">{error_html}</div>'
output.append(field_html)
return '\n'.join(output)
class PEPModelForm(forms.ModelForm):
""" 手机号-P ,email-E, password-P, 用于需要手机号,邮箱,密码的form的父类,可以多继承"""
email = forms.CharField(label="邮箱",
validators=[EmailValidator(message='请输入有效的电子邮件地址')],
widget=forms.TextInput(attrs={'class': 'form-control'})
)
# 为 phone 字段添加自定义的正则表达式验证器,这里假设手机号是 11 位数字
phone = forms.CharField(label="手机号",
validators=[
RegexValidator(
regex=r'^1[3-9]\d{9}$',
message='请输入有效的 11 位手机号码'
)
],
widget=forms.TextInput
)
password_regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$'
password_validator = RegexValidator(
regex=password_regex,
message="密码必须包含至少一个小写字母、一个大写字母、一个数字和一个特殊字符。"
)
password = forms.CharField(label="密码",
validators=[password_validator],
widget=forms.PasswordInput)
def clean_password(self):
password = self.cleaned_data.get("password")
return md5(password)
# 注册Form
class RegisterForm(BootstrapModelForm, PEPModelForm):
captcha = forms.CharField(label="验证码", widget=forms.TextInput())
confirm_password = forms.CharField(label="确认密码", widget=forms.PasswordInput(render_value=True))
class Meta:
model = Admin
# 字段按照顺序加载
fields = ['username', 'password', 'confirm_password', 'captcha', 'phone', 'email']
widgets = {
"password": forms.PasswordInput(render_value=True)
}
def clean_confirm_password(self):
password = self.cleaned_data.get("password")
confirm_password = self.cleaned_data.get("confirm_password")
if md5(confirm_password) != password:
raise ValidationError("密码不一致")
return confirm_password
我放到了login_view.py
里面了
import io
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.views.decorators.csrf import csrf_exempt
from appTang.forms import LoginForm, RegisterForm
from appTang.models import Admin
from appTang.util.captcha_utils import generate_captcha
def register(request):
""" 注册页面 """
if request.method == 'GET':
user = RegisterForm()
return render(request, 'login/register.html', {"user": user})
user = RegisterForm(data=request.POST)
# print(user)
if user.is_valid():
# 校验验证码
captcha = request.POST.get("captcha")
image_code = request.session.get('captcha', '') # 超时时,没有,给他个''
# 不区分大小写比较
if image_code.upper() == captcha.upper():
user.save()
return redirect("/login/")
else:
RegisterForm(data=request.POST)
user.add_error('captcha', '验证码输入错误')
return render(request, 'login/register.html', {"user": user})
register.html
{% load static %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户注册</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.css' %}"/>
<style>
body {
background-color: #f8f9fa;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.register-card {
background-color: white;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
padding: 2rem;
width: 350px;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
height: calc(2.25rem + 2px);
}
.btn-register {
width: 100%;
padding: 0.75rem;
background-color: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn-register:hover {
background-color: #218838;
}
.login-link {
text-align: center;
margin-top: 1rem;
}
.login-link a {
color: #007bff;
text-decoration: none;
}
.login-link a:hover {
text-decoration: underline;
}
/* 验证码相关样式 */
.captcha-group {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1.5rem;
}
.captcha-group img {
cursor: pointer;
margin-left: 10px;
}
</style>
</head>
<body>
<div class="container register-card">
<h2 class="text-center mb-4">用户注册</h2>
<form method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label>用户名:</label>
{{ user.username }}
<span style="color: red">{{ user.username.errors.0 }}</span>
</div>
<div class="form-group">
<label>密码:</label>
{{ user.password }}
<span style="color: red">{{ user.password.errors.0 }}</span>
</div>
<div class="form-group">
<label>确认密码:</label>
{{ user.confirm_password }}
<span style="color: red">{{ user.confirm_password.errors.0 }}</span>
</div>
<div class="form-group">
<label>邮箱:</label>
{{ user.email }}
<span style="color: red">{{ user.email.errors.0 }}</span>
</div>
<div class="form-group">
<label>手机号:</label>
{{ user.phone }}
<span style="color: red">{{ user.phone.errors.0 }}</span>
</div>
<div class="form-group captcha-group">
<label for="captcha">验证码:</label>
<div class="captcha-input-img">
<img id="captcha-image" class="img-fluid" src="/captcha/get">
{{ user.captcha }}
<span style="color: red">{{ user.captcha.errors.0 }}</span>
</div>
</div>
<button type="submit" class="btn-register">注册</button>
</form>
<div class="login-link">
已有账号?<a href="/login/">立即登录</a>
</div>
</div>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.js' %}"></script>
<script>
$(document).ready(function () {
$('#captcha-image').click(function () {
$.ajax({
url: '/captcha/get',
type: 'GET',
success: function (response) {
$('#captcha-image').attr('src', '/captcha/get');
$('input[name="captcha"]').val('');
},
error: function () {
alert('刷新验证码失败');
}
});
});
});
</script>
</body>
</html>