257 lines
9.9 KiB
Python
257 lines
9.9 KiB
Python
"""
|
||
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订单编号显示
|
||
|