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