django_project_demo/app/utils/form.py

257 lines
9.9 KiB
Python
Raw Normal View History

2024-08-24 11:25:23 +08:00
"""
ModelForm类
"""
from app.utils.bootstrap import BootstrapModelForm # 导入表单控件的bootstrap属性样式
from django.core.validators import RegexValidator # 进行数据校验的正则表达式
from django.core.exceptions import ValidationError # 捕获表单提交的异常错误
from app.models import UserInfo, PrettyNumber, Admin, Order # 数据表类
from django import forms # 构建表单模型
from app.utils.encrypt import md5
class UserModelForm(BootstrapModelForm):
"""
用户类表单模型
作用用于定义渲染到前端的数据设置校验规则等
用法
用ModelForm来操作表记录
1.基本用法首先从django.forms导入ModelForm
2.编写一个自己的类继承ModelForm
3.在新类里设置元类Meta
4.在Meta中设置model属性为你要关联的ORM模型这里是UserInfo
5.在Meta中设置fields属性为你要在表单中使用的字段列表
6.列表里的值应该是ORM模型model中的字段名
继承BootstrapModelForm类实现表单控件属性样式
"""
# 重新定义name字段的属性和校验规则
name = forms.CharField(min_length=2, label='姓名')
class Meta:
model = UserInfo # 指定需要显示的表名在models.py中定义
# 指定要操作的字段名,是一个列表
fields = ['name', 'age', 'gender', 'depart', 'create_time', 'account']
# 给表单控件逐个添加属性
# widgets = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'password': forms.PasswordInput(attrs={'class': 'form-control'}),
# 'create_time': forms.DateInput(attrs={'class': 'form-control'}),
# }
class PrettyNumberForm(BootstrapModelForm):
"""
靓号类表单模型
具体使用注解见UserModelForm类
继承BootstrapModelForm类实现表单控件属性样式
"""
# 重新定义mobile字段的属性和校验规则 方式1
mobile = forms.CharField(
min_length=11, # 最小长度
label='号码',
# 通过正则进行数据校验
validators=[RegexValidator(r'^1[3-9]\d{9}$', '号码错误,长度不能超过11位')],
)
class Meta:
model = PrettyNumber # 指定需要显示的表名在models.py中定义
# 指定要操作的字段名,是一个列表
# fields = ['mobile', 'price', 'level', 'status']
fields = '__all__' # 渲染所有字段
# exclude = ['level'] # 排除某个字段
# 对字段进行一些数据校验或操作 方式2
# 名称必须是clean_字段名
# 也称为钩子方法,更灵活,比如手机号是否已经存在...
def clean_mobile(self):
txt_value = self.cleaned_data['mobile'] # 获取到用户输入的字段值
num_exist = PrettyNumber.objects.filter(mobile=txt_value).exists()
if num_exist:
raise ValidationError("号码已经存在")
return txt_value
class PrettyNumberEditForm(BootstrapModelForm):
"""
靓号编辑类表单模型
具体使用注解见UserModelForm类
继承BootstrapModelForm类实现表单控件属性样式
"""
# 重新定义mobile字段的属性和校验规则 方式1
mobile = forms.CharField(
label='号码',
disabled=True,
)
class Meta:
model = PrettyNumber # 指定需要显示的表名在models.py中定义
# 指定要操作的字段名,是一个列表
# fields = ['mobile', 'price', 'level', 'status']
fields = '__all__' # 渲染所有字段
# 对字段进行一些数据校验或操作 方式2
# 名称必须是clean_字段名
# 也称为钩子方法,更灵活,比如手机号是否已经存在...
def clean_mobile(self):
txt_value = self.cleaned_data['mobile'] # 获取到用户输入的字段值
# instance是编辑时传入的值pk是id主键
nid = self.instance.id
# print(self.instance.mobile)
# 修改时,要排除当前号码以外的其他数据
# 也就是 where mobile=18900000000 and id!=2
num_exist = PrettyNumber.objects.filter(mobile=txt_value).exclude(id=nid)
if num_exist:
raise ValidationError("号码已经存在")
return txt_value
class AdminForm(BootstrapModelForm):
"""
管理员类表单模型
具体使用注解见UserModelForm类
继承BootstrapModelForm类实现表单控件属性样式
"""
# 再生成一个确认密码输入框
confirm_password = forms.CharField(
label='确认密码',
# render_value=True 不清空密码框
widget=forms.PasswordInput(render_value=True),
max_length=64)
class Meta:
model = Admin # 指定需要显示的表名在models.py中定义
# 指定要操作的字段名,是一个列表
# fields = ['mobile', 'price', 'level', 'status']
fields = '__all__' # 渲染所有字段
widgets = {
'password': forms.PasswordInput(render_value=True),
}
# exclude = ['level'] # 排除某个字段
# 对字段进行一些数据校验或操作 方式2
# 名称必须是clean_字段名
# 也称为钩子方法,更灵活,比如手机号是否已经存在...
def clean_confirm_password(self):
password_value = self.cleaned_data['password'] # 获取到用户输入的字段值此时密码已经md5加密了
confirm_password_value = md5(self.cleaned_data['confirm_password']) # 对确认框也进行md5加密
if password_value != confirm_password_value: # 两个密文之间进行比对
raise ValidationError('密码两次输入不一致')
# 返回什么就保存到数据库中什么,在这儿因为再次输入的密码不保存,所以只返回
return confirm_password_value # 又保存到cleaned_data中了
def clean_password(self):
# 对密码明文进行md5加密
password_value = self.cleaned_data['password'] # 获取到用户输入的字段值
return md5(password_value)
def clean_username(self):
# 判断输入的管理员帐户是否已经存在
username_value = self.cleaned_data['username']
username_exist = Admin.objects.filter(username=username_value).exists()
if username_exist:
raise ValidationError('用户名已存在')
# 返回什么就保存到数据库中什么,在这儿因为再次输入的密码不保存,所以只返回
return username_value # 又保存到cleaned_data中了
class AdminEditForm(BootstrapModelForm):
"""
管理员姓名修改类表单模型
具体使用注解见UserModelForm类
继承BootstrapModelForm类实现表单控件属性样式
"""
class Meta:
model = Admin
fields = ['username']
# 对字段进行一些数据校验或操作 方式2
# 名称必须是clean_字段名
# 也称为钩子方法,更灵活,比如手机号是否已经存在...
def clean_username(self):
# 判断输入的管理员帐户是否已经存在
username_value = self.cleaned_data['username']
username_exist = Admin.objects.filter(username=username_value).exists()
if username_exist:
raise ValidationError('用户名已存在')
# 返回什么就保存到数据库中什么,在这儿因为再次输入的密码不保存,所以只返回
return username_value # 又保存到cleaned_data中了
class AdminResetForm(BootstrapModelForm):
"""
管理员重置密码类表单模型
具体使用注解见UserModelForm类
继承BootstrapModelForm类实现表单控件属性样式
"""
# 再生成一个确认密码输入框
confirm_password = forms.CharField(
label='确认密码',
# render_value=True 不清空密码框
widget=forms.PasswordInput(render_value=True),
max_length=64)
class Meta:
model = Admin
fields = ['password', 'confirm_password']
widgets = {
'password': forms.PasswordInput(render_value=True),
}
# 对字段进行一些数据校验或操作 方式2
# 名称必须是clean_字段名
# 也称为钩子方法,更灵活,比如手机号是否已经存在...
def clean_confirm_password(self):
password_value = self.cleaned_data.get('password') # 获取到用户输入的字段值此时密码已经md5加密了
confirm_password_value = md5(self.cleaned_data.get('confirm_password')) # 对确认框也进行md5加密
if password_value != confirm_password_value: # 两个密文之间进行比对
raise ValidationError('密码两次输入不一致')
# 返回什么就保存到数据库中什么,在这儿因为再次输入的密码不保存,所以只返回
return confirm_password_value # 又保存到cleaned_data中了
def clean_password(self):
# 对密码明文进行md5加密
password_value = self.cleaned_data.get('password') # 获取到用户输入的字段值
md5_pwd = md5(password_value)
# 去数据库检验当前新密码是否和原密码一致
# instance是编辑时传入的值pk是id主键
pwd = Admin.objects.filter(id=self.instance.pk, password=md5_pwd).exists()
if pwd:
raise ValidationError("密码未做修改")
return md5_pwd
class OrderModelForm(BootstrapModelForm):
"""
订单类表单模型
作用用于定义渲染到前端的数据设置校验规则等
继承BootstrapModelForm类实现表单控件属性样式
"""
#
# # 重新定义name字段的属性和校验规则
# name = forms.CharField(min_length=2, label='姓名')
class Meta:
model = Order # 指定需要显示的表名
fields = '__all__'
exclude =['oid','user'] # 排除oid订单编号显示