|
|
# hyt:
|
|
|
|
|
|
from django import forms
|
|
|
from django.contrib.auth import get_user_model, password_validation
|
|
|
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
|
|
|
from django.core.exceptions import ValidationError
|
|
|
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,添加Bootstrap样式支持
|
|
|
"""
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
"""初始化表单,设置用户名和密码输入框的样式和占位符"""
|
|
|
super(LoginForm, self).__init__(*args, **kwargs)
|
|
|
# 设置用户名输入框样式
|
|
|
self.fields['username'].widget = widgets.TextInput(
|
|
|
attrs={'placeholder': "username", "class": "form-control"})
|
|
|
# 设置密码输入框样式
|
|
|
self.fields['password'].widget = widgets.PasswordInput(
|
|
|
attrs={'placeholder': "password", "class": "form-control"})
|
|
|
|
|
|
|
|
|
class RegisterForm(UserCreationForm):
|
|
|
"""
|
|
|
用户注册表单
|
|
|
|
|
|
功能:处理新用户注册,包含用户名、邮箱和密码验证
|
|
|
扩展Django标准UserCreationForm,添加邮箱验证和表单样式
|
|
|
"""
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
"""初始化表单,设置所有字段的Bootstrap样式和占位符"""
|
|
|
super(RegisterForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
# 设置各字段的表单控件样式
|
|
|
self.fields['username'].widget = widgets.TextInput(
|
|
|
attrs={'placeholder': "username", "class": "form-control"})
|
|
|
self.fields['email'].widget = widgets.EmailInput(
|
|
|
attrs={'placeholder': "email", "class": "form-control"})
|
|
|
self.fields['password1'].widget = widgets.PasswordInput(
|
|
|
attrs={'placeholder': "password", "class": "form-control"})
|
|
|
self.fields['password2'].widget = widgets.PasswordInput(
|
|
|
attrs={'placeholder': "repeat password", "class": "form-control"})
|
|
|
|
|
|
def clean_email(self):
|
|
|
"""
|
|
|
邮箱唯一性验证
|
|
|
|
|
|
功能:验证邮箱是否已被注册
|
|
|
返回:验证通过的邮箱
|
|
|
异常:邮箱已存在时抛出ValidationError
|
|
|
"""
|
|
|
email = self.cleaned_data['email']
|
|
|
if get_user_model().objects.filter(email=email).exists():
|
|
|
raise ValidationError(_("email already exists"))
|
|
|
return email
|
|
|
|
|
|
class Meta:
|
|
|
"""表单元数据配置"""
|
|
|
model = get_user_model() # 使用当前激活的用户模型
|
|
|
fields = ("username", "email") # 表单包含的字段
|
|
|
|
|
|
|
|
|
class ForgetPasswordForm(forms.Form):
|
|
|
"""
|
|
|
忘记密码重置表单
|
|
|
|
|
|
功能:处理密码重置流程,包含邮箱验证、验证码校验和新密码设置
|
|
|
用于用户通过邮箱和验证码找回密码的场景
|
|
|
"""
|
|
|
|
|
|
# 新密码字段
|
|
|
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):
|
|
|
"""
|
|
|
新密码确认验证
|
|
|
|
|
|
功能:验证两次输入的新密码是否一致并符合密码策略
|
|
|
返回:验证通过的密码
|
|
|
异常:密码不匹配或不符合策略时抛出ValidationError
|
|
|
"""
|
|
|
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"))
|
|
|
password_validation.validate_password(password2) # Django密码策略验证
|
|
|
|
|
|
return password2
|
|
|
|
|
|
def clean_email(self):
|
|
|
"""
|
|
|
邮箱存在性验证
|
|
|
|
|
|
功能:验证邮箱是否在系统中注册
|
|
|
返回:验证通过的邮箱
|
|
|
异常:邮箱未注册时抛出ValidationError
|
|
|
"""
|
|
|
user_email = self.cleaned_data.get("email")
|
|
|
if not BlogUser.objects.filter(email=user_email).exists():
|
|
|
# 安全提示:这里的报错会暴露邮箱是否注册,可根据安全需求调整
|
|
|
raise ValidationError(_("email does not exist"))
|
|
|
return user_email
|
|
|
|
|
|
def clean_code(self):
|
|
|
"""
|
|
|
验证码校验
|
|
|
|
|
|
功能:验证邮箱验证码的有效性
|
|
|
返回:验证通过的验证码
|
|
|
异常:验证码无效时抛出ValidationError
|
|
|
"""
|
|
|
code = self.cleaned_data.get("code")
|
|
|
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'), # 邮箱标签
|
|
|
)
|