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订单编号显示
|
|||
|
|