|
|
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):
|
|
|
#xh:用户登录表单,继承自Django内置的AuthenticationForm,提供用户认证功能
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
#xh:初始化方法,自定义表单字段的widget属性,设置输入框的placeholder和CSS类
|
|
|
super(LoginForm, self).__init__(*args, **kwargs)
|
|
|
# xh:设置用户名字段的输入框属性
|
|
|
self.fields['username'].widget =widgets.TextInput(
|
|
|
attrs={
|
|
|
'placeholder': "username", # xh:占位符文本
|
|
|
"class": "form-control" # xh:Bootstrap样式类
|
|
|
})
|
|
|
# 设置密码字段的输入框属性
|
|
|
self.fields['password'].widget = widgets.PasswordInput(
|
|
|
attrs={
|
|
|
'placeholder': "password", # xh:占位符文本
|
|
|
"class": "form-control" # xh:Bootstrap样式类
|
|
|
})
|
|
|
|
|
|
|
|
|
class RegisterForm(UserCreationForm):
|
|
|
#xh:用户注册表单,继承自Django内置的UserCreationForm,提供用户注册功能,自动包含密码验证逻辑(密码强度、两次密码一致性等)
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
#xh:初始化方法,自定义所有表单字段的widget属性
|
|
|
super(RegisterForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
# xh:设置用户名字段的输入框属性
|
|
|
self.fields['username'].widget = widgets.TextInput(
|
|
|
attrs={'placeholder': "username", "class": "form-control"})
|
|
|
|
|
|
# xh:设置邮箱字段的输入框属性
|
|
|
self.fields['email'].widget = widgets.EmailInput(
|
|
|
attrs={'placeholder': "email", "class": "form-control"})
|
|
|
|
|
|
# xh:设置密码字段的输入框属性
|
|
|
self.fields['password1'].widget = widgets.PasswordInput(
|
|
|
attrs={'placeholder': "password", "class": "form-control"})
|
|
|
|
|
|
# xh:设置确认密码字段的输入框属性
|
|
|
self.fields['password2'].widget = widgets.PasswordInput(
|
|
|
attrs={'placeholder': "repeat password", "class": "form-control"})
|
|
|
|
|
|
def clean_email(self):
|
|
|
#xh:邮箱字段验证方法,确保邮箱地址在系统中唯一
|
|
|
email = self.cleaned_data['email']
|
|
|
# xh:检查邮箱是否已存在
|
|
|
if get_user_model().objects.filter(email=email).exists():
|
|
|
raise ValidationError(_("email already exists"))
|
|
|
return email
|
|
|
|
|
|
class Meta:
|
|
|
#xh:表单元数据配置"""
|
|
|
model = get_user_model() # xh:使用项目中配置的用户模型
|
|
|
fields = ("username", "email") # xh:表单包含的字段
|
|
|
|
|
|
|
|
|
class ForgetPasswordForm(forms.Form):
|
|
|
#xh:忘记密码表单(用于验证码和密码重置),包含新密码设置、邮箱验证和验证码验证
|
|
|
|
|
|
# xh:新密码字段
|
|
|
new_password1 = forms.CharField(
|
|
|
label=_("New password"), # xh:字段标签(支持国际化)
|
|
|
widget=forms.PasswordInput(
|
|
|
attrs={
|
|
|
"class": "form-control", # xh:Bootstrap样式
|
|
|
'placeholder': _("New password") # xh:占位符文本
|
|
|
}
|
|
|
),
|
|
|
)
|
|
|
|
|
|
# xh:确认密码字段
|
|
|
new_password2 = forms.CharField(
|
|
|
label="确认密码", # xh:中文标签
|
|
|
widget=forms.PasswordInput(
|
|
|
attrs={
|
|
|
"class": "form-control",
|
|
|
'placeholder': _("Confirm password") # xh:英文占位符
|
|
|
}
|
|
|
),
|
|
|
)
|
|
|
|
|
|
# xh:邮箱字段(用于验证用户身份)
|
|
|
email = forms.EmailField(
|
|
|
label='邮箱', # xh:中文标签
|
|
|
widget=forms.TextInput( # xh:使用TextInput而不是EmailInput以便更好地控制样式
|
|
|
attrs={
|
|
|
'class': 'form-control',
|
|
|
'placeholder': _("Email")
|
|
|
}
|
|
|
),
|
|
|
)
|
|
|
|
|
|
# xh:验证码字段(用于二次验证)
|
|
|
code = forms.CharField(
|
|
|
label=_('Code'), # xh:验证码标签
|
|
|
widget=forms.TextInput(
|
|
|
attrs={
|
|
|
'class': 'form-control',
|
|
|
'placeholder': _("Code")
|
|
|
}
|
|
|
),
|
|
|
)
|
|
|
|
|
|
def clean_new_password2(self):
|
|
|
#xh:确认密码验证方法,验证两次输入的密码是否一致,并检查密码强度
|
|
|
password1 = self.data.get("new_password1")
|
|
|
password2 = self.data.get("new_password2")
|
|
|
|
|
|
# xh:检查两次密码是否一致
|
|
|
if password1 and password2 and password1 != password2:
|
|
|
raise ValidationError(_("passwords do not match"))
|
|
|
|
|
|
# xh:使用Django内置的密码验证器验证密码强度
|
|
|
password_validation.validate_password(password2)
|
|
|
|
|
|
return password2
|
|
|
|
|
|
def clean_email(self):
|
|
|
#xh:邮箱验证方法,验证邮箱是否在系统中已注册
|
|
|
user_email = self.cleaned_data.get("email")
|
|
|
# xh:检查邮箱是否存在(是否已注册)
|
|
|
if not BlogUser.objects.filter(email=user_email).exists():
|
|
|
# TODO: 这里的报错提示可能会暴露邮箱是否注册,根据安全需求可以修改
|
|
|
raise ValidationError(_("email does not exist"))
|
|
|
return user_email
|
|
|
|
|
|
def clean_code(self):
|
|
|
#xh:验证码验证方法,调用utils模块的验证函数检查验证码是否正确
|
|
|
code = self.cleaned_data.get("code")
|
|
|
# xh:调用验证工具函数检查验证码
|
|
|
error = utils.verify(
|
|
|
email=self.cleaned_data.get("email"), # xh:传入邮箱
|
|
|
code=code, # xh:传入验证码
|
|
|
)
|
|
|
if error:
|
|
|
raise ValidationError(error) # xh:验证失败,抛出错误
|
|
|
return code
|
|
|
|
|
|
|
|
|
class ForgetPasswordCodeForm(forms.Form):
|
|
|
#xh:忘记密码验证码请求表单,简化版表单,仅用于请求发送密码重置验证码
|
|
|
|
|
|
email = forms.EmailField(
|
|
|
label=_('Email'), # xh:只需要邮箱字段来请求发送验证码
|
|
|
) |