You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Django/doc/accounts/forms.py

153 lines
6.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 导入Django表单基类
from django import forms
# 导入Django用户模型工具及密码验证功能
from django.contrib.auth import get_user_model, password_validation
# 导入Django内置的认证表单登录、用户创建
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
# 导入Django验证错误类用于自定义表单验证
from django.core.exceptions import ValidationError
# 导入Django表单控件用于自定义输入框样式
from django.forms import widgets
# 导入翻译工具,实现字段名称/提示的国际化
from django.utils.translation import gettext_lazy as _
# 导入自定义工具类(可能用于验证码验证等)
from . import utils
# 导入自定义用户模型
from .models import BlogUser
class LoginForm(AuthenticationForm):
"""自定义登录表单继承自Django内置的AuthenticationForm"""
def __init__(self, *args, **kwargs):
"""初始化方法,重写父类初始化逻辑以自定义表单控件样式"""
super(LoginForm, self).__init__(*args, **kwargs)
# 自定义用户名字段的输入控件设置占位符和CSS类
self.fields['username'].widget = widgets.TextInput(
attrs={'placeholder': "username", "class": "form-control"})
# 自定义密码字段的输入控件使用密码输入框设置占位符和CSS类
self.fields['password'].widget = widgets.PasswordInput(
attrs={'placeholder': "password", "class": "form-control"})
class RegisterForm(UserCreationForm):
"""自定义注册表单继承自Django内置的UserCreationForm"""
def __init__(self, *args, **kwargs):
"""初始化方法,重写父类初始化逻辑以自定义表单控件样式"""
super(RegisterForm, self).__init__(*args, **kwargs)
# 自定义用户名字段控件文本输入框设置占位符和CSS类
self.fields['username'].widget = widgets.TextInput(
attrs={'placeholder': "username", "class": "form-control"})
# 自定义邮箱字段控件邮箱输入框设置占位符和CSS类
self.fields['email'].widget = widgets.EmailInput(
attrs={'placeholder': "email", "class": "form-control"})
# 自定义密码1字段控件密码输入框设置占位符和CSS类
self.fields['password1'].widget = widgets.PasswordInput(
attrs={'placeholder': "password", "class": "form-control"})
# 自定义密码2字段控件密码输入框确认密码设置占位符和CSS类
self.fields['password2'].widget = widgets.PasswordInput(
attrs={'placeholder': "repeat password", "class": "form-control"})
def clean_email(self):
"""自定义邮箱验证:检查邮箱是否已被注册"""
email = self.cleaned_data['email']
# 如果该邮箱已存在于用户表中,抛出验证错误
if get_user_model().objects.filter(email=email).exists():
raise ValidationError(_("email already exists"))
return email
class Meta:
# 关联的用户模型通过get_user_model获取项目配置的用户模型
model = get_user_model()
# 注册表单需填写的字段:用户名和邮箱
fields = ("username", "email")
class ForgetPasswordForm(forms.Form):
"""忘记密码表单,用于用户重置密码(包含密码重置、邮箱验证、验证码验证)"""
# 新密码字段标签国际化使用密码输入框设置CSS类和占位符
new_password1 = forms.CharField(
label=_("New password"),
widget=forms.PasswordInput(
attrs={
"class": "form-control",
'placeholder': _("New password")
}
),
)
# 确认新密码字段:标签为“确认密码”,使用密码输入框,设置样式
new_password2 = forms.CharField(
label="确认密码",
widget=forms.PasswordInput(
attrs={
"class": "form-control",
'placeholder': _("Confirm password")
}
),
)
# 邮箱字段:用于验证用户身份,使用文本输入框,设置样式
email = forms.EmailField(
label='邮箱',
widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': _("Email")
}
),
)
# 验证码字段:用于验证用户真实性,使用文本输入框,设置样式
code = forms.CharField(
label=_('Code'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': _("Code")
}
),
)
def clean_new_password2(self):
"""验证两次输入的新密码是否一致,并验证密码强度"""
password1 = self.data.get("new_password1") # 获取第一次输入的密码
password2 = self.data.get("new_password2") # 获取第二次输入的密码
# 如果两次密码都存在且不一致,抛出验证错误
if password1 and password2 and password1 != password2:
raise ValidationError(_("passwords do not match"))
# 使用Django内置密码验证器验证密码强度如长度、复杂度等
password_validation.validate_password(password2)
return password2
def clean_email(self):
"""验证邮箱是否已注册(存在于用户表中)"""
user_email = self.cleaned_data.get("email")
# 如果该邮箱不存在于BlogUser表中抛出验证错误
if not BlogUser.objects.filter(
email=user_email
).exists():
# 注意:此处提示可能暴露邮箱是否注册,可根据需求修改
raise ValidationError(_("email does not exist"))
return user_email
def clean_code(self):
"""验证验证码是否有效调用自定义工具类的verify方法"""
code = self.cleaned_data.get("code")
# 调用utils.verify验证邮箱和验证码是否匹配返回错误信息若有
error = utils.verify(
email=self.cleaned_data.get("email"),
code=code,
)
# 如果验证失败(有错误信息),抛出验证错误
if error:
raise ValidationError(error)
return code
class ForgetPasswordCodeForm(forms.Form):
"""获取忘记密码验证码的表单,用于提交邮箱以发送验证码"""
# 邮箱字段:用于指定需要发送验证码的邮箱,标签国际化
email = forms.EmailField(
label=_('Email'),
)