Form表单验证
1、创建Form类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 from django.forms import Form 2 from django.forms import widgets 3 from django.forms import fields 4 5 class FM(Form): 6 user = fields.CharField( 7 error_messages={'required':'用户名不能为空'} 8 ) 9 pwd = fields.CharField( 10 max_length=18, 11 min_length=9, 12 error_messages={'required':'密码不能为空','max_length':'密码长度不能大于12','min_length':'密码长度不能小于6'}, 13 widget=widgets.PasswordInput(attrs={'class':'c1','id':'i1'}) 14 ) 15 email = fields.EmailField( 16 error_messages={'required': '邮箱不能为空.', 'invalid': "邮箱格式错误"} 17 ) 18 gender = fields.ChoiceField( 19 choices=((1,'男'),(2,'女'),), 20 initial = 2, #默认值 21 # widget=widgets.Select 22 widget=widgets.RadioSelect 23 ) 24 city = fields.CharField( 25 initial=2, 26 widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) 27 ) 28 abc = fields.MultipleChoiceField( 29 choices=((1,'a'),(2,'b'),(3,'c'),(4,'d')), 30 initial=[1,2], 31 widget = widgets.CheckboxSelectMultiple 32 )
2、views函数处理
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 def form(request): 2 if request.method == 'GET': 3 obj = FM() 4 return render(request,'form.html',{'obj':obj}) 5 elif request.method == 'POST': 6 obj = FM(request.POST) 7 if obj.is_valid(): 8 values = obj.clean() 9 print(values) 10 else: 11 errors = obj.errors 12 print(errors) 13 return render(request,'form.html',{'obj':obj})
3、html页面
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form method="post" action="#"> 9 {% csrf_token %} 10 <p>{{ obj.user }}{{ obj.user.errors.0 }}</p> 11 <p>{{ obj.pwd }}{{ obj.pwd.errors.0 }}</p> 12 <p>{{ obj.email }}{{ obj.email.errors.0 }}</p> 13 <p>{{ obj.city }}{{ obj.city.errors.0 }}</p> 14 <p>{{ obj.gender }}{{ obj.gender.errors.0 }}</p> 15 <p>{{ obj.abc }}{{ obj.abc.errors.0 }}</p> 16 <input type="submit" value="提交"> 17 </form> 18 </body> 19 </html>
Form内置字段
内置字段 --> username = field.CharField(里面写方法)
Field
required=True, 是否允许为空
widget=None, HTML插件
label=None, 用于生成Label标签或显示内容
initial=None, 初始值
help_text='', 帮助信息(在标签旁边显示)
error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'}
show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
validators=[], 自定义验证规则
localize=False, 是否支持本地化
disabled=False, 是否可以编辑
label_suffix=None Label内容后缀
CharField(Field)
max_length=None, 最大长度
min_length=None, 最小长度
strip=True 是否移除用户输入空白
IntegerField(Field)
max_value=None, 最大值
min_value=None, 最小值
FloatField(IntegerField)
...
DecimalField(IntegerField)
max_value=None, 最大值
min_value=None, 最小值
max_digits=None, 总长度
decimal_places=None, 小数位长度
BaseTemporalField(Field)
input_formats=None 时间格式化
DateField(BaseTemporalField) 格式:2015-09-01
TimeField(BaseTemporalField) 格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
DurationField(Field) 时间间隔:%d %H:%M:%S.%f
...
RegexField(CharField)
regex, 自定制正则表达式
max_length=None, 最大长度
min_length=None, 最小长度
error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'}
EmailField(CharField)
...
FileField(Field)
allow_empty_file=False 是否允许空文件
ImageField(FileField)
...
注:需要PIL模块,pip3 install Pillow
以上两个字典使用时,需要注意两点:
- form表单中 enctype="multipart/form-data"
- view函数中 obj = MyForm(request.POST, request.FILES)
URLField(Field)
...
BooleanField(Field)
...
NullBooleanField(BooleanField)
...
ChoiceField(Field)
...
choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),)
required=True, 是否必填
widget=None, 插件,默认select插件
label=None, Label内容
initial=None, 初始值
help_text='', 帮助提示
ModelChoiceField(ChoiceField)
... django.forms.models.ModelChoiceField
queryset, # 查询数据库中的数据
empty_label="---------", # 默认空显示内容
to_field_name=None, # HTML中value的值对应的字段
limit_choices_to=None # ModelForm中对queryset二次筛选
ModelMultipleChoiceField(ModelChoiceField)
... django.forms.models.ModelMultipleChoiceField
TypedChoiceField(ChoiceField)
coerce = lambda val: val 对选中的值进行一次转换
empty_value= '' 空值的默认值
MultipleChoiceField(ChoiceField)
...
TypedMultipleChoiceField(MultipleChoiceField)
coerce = lambda val: val 对选中的每一个值进行一次转换
empty_value= '' 空值的默认值
ComboField(Field)
fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式
fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
MultiValueField(Field)
PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
SplitDateTimeField(MultiValueField)
input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
required=True,
widget=None,
label=None,
initial=None,
help_text=''
GenericIPAddressField
protocol='both', both,ipv4,ipv6支持的IP格式
unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
SlugField(CharField) 数字,字母,下划线,减号(连字符)
...
UUIDField(CharField) uuid类型
...
内置插件
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 TextInput(Input) 2 NumberInput(TextInput) 3 EmailInput(TextInput) 4 URLInput(TextInput) 5 PasswordInput(TextInput) 6 HiddenInput(TextInput) 7 Textarea(Widget) 8 DateInput(DateTimeBaseInput) 9 DateTimeInput(DateTimeBaseInput) 10 TimeInput(DateTimeBaseInput) 11 CheckboxInput 12 Select 13 NullBooleanSelect 14 SelectMultiple 15 RadioSelect 16 CheckboxSelectMultiple 17 FileInput 18 ClearableFileInput 19 MultipleHiddenInput 20 SplitDateTimeWidget 21 SplitHiddenDateTimeWidget 22 SelectDateWidget
常用选择插件
# 单radio,值为字符串
# user = fields.CharField(
# initial=2,
# widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
# )
# 单radio,值为字符串
# user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
# initial=2,
# widget=widgets.RadioSelect
# )
# 单select,值为字符串
# user = fields.CharField(
# initial=2,
# widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
# )
# 单select,值为字符串
# user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
# initial=2,
# widget=widgets.Select
# )
# 多选select,值为列表
# user = fields.MultipleChoiceField(
# choices=((1,'上海'),(2,'北京'),),
# initial=[1,],
# widget=widgets.SelectMultiple
# )
# 单checkbox
# user = fields.CharField(
# widget=widgets.CheckboxInput()
# )
# 多选checkbox,值为列表
# user = fields.MultipleChoiceField(
# initial=[2, ],
# choices=((1, '上海'), (2, '北京'),),
# widget=widgets.CheckboxSelectMultiple
# )
初始化数据(编辑时,显示之前的数据)
views端:
class FM(Form):
form类
...
from app01 import models
def fm(request):
if request.method == "GET":
# 从数据库中吧数据获取到
dic = {
"user": 'r1',
'pwd': '123123',
'email': 'sdfsd',
'city1': 1,
'city2': [1,2]
}
obj = FM(initial=dic)
return render(request,'fm.html',{'obj': obj})
elif request.method == "POST":
# 获取用户所有数据
# 每条数据请求的验证
# 成功:获取所有的正确的信息
# 失败:显示错误信息
obj = FM(request.POST)
r1 = obj.is_valid()
if r1:
# obj.cleaned_data
models.UserInf.objects.create(**obj.cleaned_data)
else:
# ErrorDict
# print(obj.errors.as_json())
# print(obj.errors['user'][0])
return render(request,'fm.html', {'obj': obj})
return render(request,'fm.html')
html端
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <form method="POST" enctype="multipart/form-data"> 2 {% csrf_token %} 3 <p>{{ form.user }} {{ form.user.errors }}</p> 4 <p>{{ form.city }} {{ form.city.errors }}</p> 5 6 <input type="submit"/> 7 </form>
自定义异常
a.clean_%s(self) #clean_ + 要审查的那个字段
源代码:
实现
b._post_clean(self) # 重写clean方法
源代码
实现
c.clean(self) # 重写clean方法
源代码
实现
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 views.py 2 3 from django.shortcuts import render,redirect,HttpResponse 4 5 from cmdb import models 6 from django import forms 7 from django.forms import fields 8 from django.core.exceptions import ValidationError 9 10 class UserForm(forms.Form): 11 username = fields.CharField(label='用户名') 12 email = fields.EmailField(label='email') 13 14 user_type = fields.ChoiceField(choices=models.UserType.objects.values_list('id', 'name')) 15 16 def clean_username(self): 17 # 自定义错误验证-->验证单个 18 value = self.cleaned_data['username'] 19 if value == 'root': 20 return value 21 else: 22 raise ValidationError('用户名输入错误') 23 24 def _post_clean(self): 25 # 自定义错误验证-->验证多个 26 v1 = value = self.cleaned_data['username'] 27 v2 = value = self.cleaned_data['email'] 28 if v1 == 'root' and v2 == 'alex@163.com': 29 pass 30 else: 31 self.add_error('__all__',ValidationError('用户名或邮箱输入错误')) 32 33 def clean(self): 34 v1 = value = self.cleaned_data['username'] 35 v2 = value = self.cleaned_data['email'] 36 if v1 == 'root' and v2 == 'alex@163.com': 37 pass 38 else: 39 raise ValidationError('用户名或邮箱输入错误') 40 41 42 43 def index(request): 44 if request.method == 'GET': 45 obj = UserForm() 46 return render(request,'index.html',{'obj':obj}) 47 elif request.method == 'POST': 48 obj = UserForm(request.POST) 49 print(obj.is_valid()) 50 # print(obj.clean()) 51 print(obj.cleaned_data) 52 print(obj.errors) 53 return render(request, 'index.html', {'obj': obj}) 54 55 56 index.html 57 58 <!DOCTYPE html> 59 <html lang="en"> 60 <head> 61 <meta charset="UTF-8"> 62 <title>Title</title> 63 </head> 64 <body> 65 <form action="/index/" method="post"> 66 {% csrf_token %} 67 {{ obj.as_p }} 68 <input type="submit" value="提交" /> 69 </form> 70 </body> 71 </html>
保持发送到前端的数据实时更新 # {{ obj.as_p }} {{ obj.name }} {{ obj.name.errors.0 }}
方法一:重写构造函数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 from django import forms 2 from django.forms import fields 3 4 class UserForm(forms.Form): 5 username = fields.CharField(label='用户名') 6 email = fields.EmailField(label='email') 7 8 user_type1 = fields.ChoiceField(choices=models.UserType.objects.values_list('id', 'name')) 9 10 def __init__(self,*args,**kwargs): 11 super(UserForm,self).__init__(*args,**kwargs) 12 self.fields['user_type1'].widget.choices = models.UserType.objects.all().values_list('id', 'name')
方法二:使用ModelChoiceField # 要在要调用的model写上def__str__:self.xxx
里面可以加的参数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 class UserForm(forms.Form): 2 username = fields.CharField(label='用户名') 3 email = fields.EmailField(label='email') 4 5 from django.forms import models as models_fields 6 7 user_type2 = models_fields.ModelChoiceField(queryset=models.UserType.objects.all(), 8 empty_label='请选择用户类型', 9 to_field_name="id", 10 limit_choices_to={'id': 1})