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.
DjangoBlog/accounts/forms.py

137 lines
4.9 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.

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"""
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):
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):
"""检查邮箱是否已被注册"""
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):
"""验证两次输入的新密码是否一致,并校验密码强度"""
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):
"""验证邮箱是否存在于数据库"""
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):
"""验证邮箱验证码是否正确或过期"""
code = self.cleaned_data.get("code")
error = utils.verify(
email=self.cleaned_data.get("email"),
code=code,
)
if error: # utils.verify 返回错误信息时表示验证失败
raise ValidationError(error)
return code
# ------------------------- 验证码邮箱发送表单 -------------------------
class ForgetPasswordCodeForm(forms.Form):
"""发送邮箱验证码表单,仅校验邮箱格式"""
email = forms.EmailField(
label=_('Email'),
)