咱们以前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签而且用form标签把它们包起来。与此同时咱们在好多场景下都须要对用户的输入作校验,好比校验用户是否输入,输入的长度和格式等正不正确。若是用户输入的内容有错误就须要在页面上相应的位置显示对应的错误信息。Django的form组件就实现了上面所述的功能。html
总结一下,其实form组件的主要功能以下:python
ps:django官方文档-forms-apigit
经过下面注册示例感觉一下普通方式和Form方式的差异。正则表达式
1 from django.conf.urls import url 2 from test_app import views 3 4 urlpatterns = [ 5 url(r'^register_html/', views.register_html), 6 ]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>注册</title> 6 </head> 7 <body> 8 <form action="/register_html/" method="post"> 9 {% csrf_token %} 10 <table> 11 <tr> 12 <td style="text-align: right">用户名:</td> 13 <td><input type="text" name="username" value="{{ username }}"></td> 14 <td style="color: red"> 15 {{ username_error }} 16 </td> 17 </tr> 18 <tr> 19 <td style="text-align: right">密码:</td> 20 <td><input type="password" name="userpwd" value="{{ userpwd }}"></td> 21 <td style="color: red">{{ userpwd_error }}</td> 22 </tr> 23 <tr> 24 <td style="text-align: right">确认密码:</td> 25 <td><input type="password" name="re_userpwd" value="{{ re_userpwd }}"></td> 26 <td style="color: red">{{ re_userpwd_error }}</td> 27 </tr> 28 <tr> 29 <td colspan="3" style="text-align: center"> 30 <input type="submit" value="提交"> 31 </td> 32 </tr> 33 </table> 34 </form> 35 </body> 36 </html>
1 from django.shortcuts import render, HttpResponse 2 3 4 def register_html(request): 5 if request.method == 'POST': 6 username = request.POST.get('username') 7 userpwd = request.POST.get('userpwd') 8 re_userpwd = request.POST.get('re_userpwd') 9 msg_dict = {'status': 'error', 'msg': '验证失败', 'username': username, 'userpwd': userpwd, 10 're_userpwd': re_userpwd} 11 # 限制用户名长度为6-12位 12 if len(username) < 6 or len(username) > 12: 13 msg_dict['username_error'] = '用户名长度需为6-12位' 14 print(msg_dict) 15 return render(request, 'register_html.html', msg_dict) 16 if len(userpwd) == 0: 17 msg_dict['userpwd_error'] = '密码不能为空' 18 return render(request, 'register_html.html', msg_dict) 19 # 确认两次输入密码一致 20 if userpwd != re_userpwd: 21 msg_dict['re_userpwd_error'] = '两次输入的密码必须一致' 22 return render(request, 'register_html.html', msg_dict) 23 # 上述验证都经过,下面执行注册操做 ... 24 return HttpResponse('注册成功') 25 return render(request, 'register_html.html')
1 from django.conf.urls import url 2 from test_app import views 3 4 urlpatterns = [ 5 url(r'^register_form/', views.register_form), 6 ]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>注册</title> 6 </head> 7 <body> 8 <form action="/register_form/" method="post" novalidate> 9 {% csrf_token %} 10 <table> 11 <tr> 12 <td style="text-align: right">{{ form_obj.username.label }}:</td> 13 <td>{{ form_obj.username }}</td> 14 <td style="color: red"> 15 {{ form_obj.username.errors.0 }} 16 </td> 17 </tr> 18 <tr> 19 <td style="text-align: right">{{ form_obj.userpwd.label }}:</td> 20 <td>{{ form_obj.userpwd }}</td> 21 <td style="color: red">{{ form_obj.userpwd.errors.0 }}</td> 22 </tr> 23 <tr> 24 <td style="text-align: right">{{ form_obj.re_userpwd.label }}:</td> 25 <td>{{ form_obj.re_userpwd }}</td> 26 <td style="color: red">{{ form_obj.re_userpwd.errors.0 }}</td> 27 </tr> 28 <tr> 29 <td colspan="3" style="text-align: center"> 30 <input type="submit" value="提交"> 31 </td> 32 </tr> 33 </table> 34 </form> 35 </body> 36 </html>
1 from django.shortcuts import render, HttpResponse 2 from django import forms 3 4 5 # 按照Django form组件的要求本身写一个类 6 class RegForm(forms.Form): 7 username = forms.CharField( 8 label="用户名", 9 min_length=6, 10 max_length=12, 11 initial="admin", 12 error_messages={ 13 "min_length": "用户名长度需为6-12位", 14 "max_length": "用户名长度需为6-12位", 15 } 16 ) 17 userpwd = forms.CharField( 18 label="密码", 19 required=True, 20 error_messages={ 21 "required": "密码不能为空", 22 }, 23 widget=forms.widgets.PasswordInput(render_value=True) 24 ) 25 re_userpwd = forms.CharField( 26 label="确认密码", 27 required=True, 28 error_messages={ 29 "required": "密码不能为空", 30 }, 31 widget=forms.widgets.PasswordInput(render_value=True) 32 ) 33 34 # 校验时会调用 35 def clean(self): 36 data = self.cleaned_data 37 userpwd = data.get('userpwd') 38 re_userpwd = data.get('re_userpwd') 39 if userpwd != re_userpwd: 40 self.add_error('re_userpwd', '两次输入的密码必须一致') 41 return data
指定某个字段是必需的。django
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", required=True ) pwd = forms.CharField(min_length=6, label="密码")
label参数用来指定页面中字段的标题,若是不指定,Field经过将字段名的全部下划线转换为空格和第一个字母的大写生成默认label。后端
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", ) pwd = forms.CharField(min_length=6, label="密码")
给label指定后缀。api
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", label_suffix=':' ) pwd = forms.CharField(min_length=6, label="密码")
给字段指定默认(初始)值。若要指定动态初始数据,请参见Form.initial
参数。服务器
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="张三" # 设置默认值 ) pwd = forms.CharField(min_length=6, label="密码")
widget参数用于使用指定的Widget类来呈现Field(例如数字)。(小部件的更多信息)app
help_text参数容许为Field指定描述性文本。若是提供help_text参数,它将显示在Field后。ide
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, max_length=32, label="用户名", help_text='32 characters max.' ) pwd = forms.CharField(min_length=6, label="密码")
用来重写错误信息。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="张三", error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短8位" } ) pwd = forms.CharField(min_length=6, label="密码")
validators参数容许为该字段提供验证函数的列表。(想了解更多信息见验证器文档)。
# 限定偶数验证器 from django import forms from django.core.exceptions import ValidationError def validate_even(value): print(value) if value % 2 != 0: raise ValidationError( '%(value)s is not an even number', params={'value': value}, ) class SimpleForm(forms.Form): even_field = forms.IntegerField(validators=[validate_even])
from django import forms from django.core.validators import RegexValidator class SimpleForm(forms.Form): phone_number = forms.CharField( validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]{8}$', '数字必须以159开头且11位')], )
localize参数支持表单数据输入和呈现输出的本地化。(想了解更多信息见格式本地化文档)。
该参数为布尔类型,设置为True,则禁用表单字段,使其不能被用户编辑。即便用户篡改了提交给服务器的字段的值,它也会被忽略。
forms库附带了一组常见验证需求的Field类。本节记录一部份内置字段。想了解更多可参考Django官方文档。
对于每一个字段,描述了不指定widget时使用的默认小部件类。还描述了在表单中提供空值时后台所对应的值(请参阅required了解这意味着什么)。
False
True或False
值是否为True(若是字段具备required=True)
例如,选中复选框。
required
由于Field
类默认required=True。若是要在窗体中包含一个布尔值,能够选择True
或False
(例如选中或未选中复选框),必须记住传入required=False
建立BooleanField
.
字符串。
max_length
或min_length
,若是提供的话。不然,全部输入都是有效的。
required
, max_length
, min_length
若是提供了这些参数,则确保字符串最多或至少为给定长度。
若是True(默认),该值将被去掉前导和尾随空格。
ChoiceField
''
(空字符串)
字符串。
给定值是否存在于选项列表中。
required
, invalid_choice
接收一个元组(列表)序列或返回该序列的函数句柄。
1 def choiceList(): 2 return [(1, '张三'), (2, '李四')] 3 4 5 class TestForm(forms.Form): 6 f1 = forms.ChoiceField(choices=choiceList) 7 f2 = forms.ChoiceField(choices=[(1, '张三'), (2, '李四')])
TypedChoiceField
由coerce参数决定。
给定值是否存在于选项列表中,并可强制执行。
required
, invalid_choice
coerce
该参数接受一个函数,这个函数接受一个参数并返回一个的值做为cleaned_data中的值,而这个参数正是用户选择的值。返回值能够是int
, float
, bool
以及其余类型。
1 from django.shortcuts import render, HttpResponse 2 from django import forms 3 4 5 def choiceList(): 6 return [(1, '张三'), (2, '李四')] 7 8 9 def coerceFunc(value): 10 return ['选择的是{}'.format(tuple[1]) for tuple in choiceList() if tuple[0] == int(value)][0] 11 12 13 class TestForm(forms.Form): 14 f1 = forms.TypedChoiceField(choices=choiceList, coerce=coerceFunc) 15 16 17 def test(request): 18 form_obj = TestForm() 19 if request.method == 'POST': 20 form_obj = TestForm(request.POST) 21 if form_obj.is_valid(): 22 print(form_obj.cleaned_data.get('f1')) # 选择的是张三 23 24 return render(request, 'test.html', {'form_obj': form_obj})
None
datetime.date
给定值是否为datetime.date
, datetime.datetime
或以特定日期格式化的字符串。
required
, invalid
用于尝试将字符串转换为有效的格式的列表。datetime.date
对象。
若是没有input_formats
参数,默认输入格式以下:
['%Y-%m-%d', # '2006-10-25' '%m/%d/%Y', # '10/25/2006' '%m/%d/%y'] # '10/25/06'
此外,若是指定USE_L10N=False
在您的设置中,默认输入格式还将包括下列内容:
['%b %d %Y', # 'Oct 25 2006' '%b %d, %Y', # 'Oct 25, 2006' '%d %b %Y', # '25 Oct 2006' '%d %b, %Y', # '25 Oct, 2006' '%B %d %Y', # 'October 25 2006' '%B %d, %Y', # 'October 25, 2006' '%d %B %Y', # '25 October 2006' '%d %B, %Y'] # '25 October, 2006'
另见格式本地化。
None
datetime.datetime
给定值是否为datetime.datetime
, datetime.date
或以特定日期时间格式化的字符串。
required
,invalid
用于尝试将字符串转换为datetime.datetime
对象的有效的格式的列表。。
若是没有input_formats
参数,默认输入格式以下:
['%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' '%Y-%m-%d %H:%M', # '2006-10-25 14:30' '%Y-%m-%d', # '2006-10-25' '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' '%m/%d/%Y %H:%M', # '10/25/2006 14:30' '%m/%d/%Y', # '10/25/2006' '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' '%m/%d/%y %H:%M', # '10/25/06 14:30' '%m/%d/%y'] # '10/25/06'
另见格式本地化.
DecimalField
localize=
False时为
NumberInput,localize=True时为
TextInput。
None
decimal
给定值是否为十进制格式,前导和尾随空格会被忽略。
required
,invalid
,max_value
,min_value
,max_digits
,max_decimal_places
,max_whole_digits
max_value和min_value错误消息可能包含%(limit_value)s,它将被适当的限制所取代。相似地,max_digits, max_decimal_places和max_whole_digits错误消息可能包含%(max)s.
控制字段中容许值的范围(最小值和最大值)。
值中容许的最大数字数(小数点以前的数字加上小数点以后的数字,并去掉前导零)。
容许的最大小数位数。
DurationField
None
给定值是否为可转换为timedelta。
required
, invalid
接收任何可经过parse_duration()转换的值。
''
(空字符串)
字符串
使用一个中等复杂的正则表达式验证给定的值是不是一个有效的电子邮件地址。
required
, invalid
有两个用于验证的可选参数,max_length和min_length。若是提供了这些参数,则确保字符串最多或至少为给定长度。
None
UploadedFile
对象,该对象将文件内容和文件名包装到单个对象中。
非空文件数据是否已绑定到控件。
required
, invalid
, missing
, empty
, max_length
有两个用于验证的可选参数,max_length和allow_empty_file。若是提供,则确保文件名最多为给定长度,即便文件内容为空,验证也将成功。
想了解更多关于UploadedFile
对象,请参阅文件上载文档。
当你在form中使用FileField时
,还必须记住将文件数据绑定到窗体.
max_length
是指文件名的长度。在该键的错误消息中,%(max)d
将被替换为最大文件名长度和%(length)d
将被替换为当前文件名长度。
None
字符串
所选项是否存在于选项列表中。
required
, invalid_choice
其内容所在目录的绝对路径。这个目录必须存在。
若是是False,
直接将path下内容提供做为选择。若是True
,目录将被递归地将全部的后代做为选择列出。
正则表达式模式,只有具备与此表达式匹配的名称的文件才容许做为选择。
可选的。True
或False
。默认值是True
。指定是否包括指定位置中的文件。若是这个是False那么allow_folders
必定是True。
可选的。True
或False
。默认值是False
。指定是否应包括指定位置中的文件夹。若是这个是False那么allow_files
必定是True
.
None
UploadedFile
对象,该对象将文件内容和文件名包装到单个对象中。
文件数据是否已绑定到表单,而且该文件是否具备由Pillow可解析的图像格式。
required
, invalid
, missing
, empty
, invalid_image
要使用ImageField,要求已安装的Pillow支持该格式。
若是在上传的时候遇到corrupt image error,这一般表示Pillow不能解析该格式。要解决这个问题,请安装适当的库并从新安装Pillow。
当在表单上使用ImageField时
,还必须记住将文件数据绑定到窗体。
在清理和验证字段后,UploadedFile
对象将有一个额外image属性,它包含Pillow的image实例,用于检查文件是否为有效图像。还有,UploadedFile.content_type
将被更新为图像的内容类型,前提是Pillow能够解析它,不然它将被设置为None
.
GenericIPAddressField
''
(空字符串)
字符串
给定值是否为有效的IP地址。
required
, invalid
限制指定协议的有效输入,默认值是both
,IPv4
或IPv6
。匹配是不区分大小写的。
解包IPv 4映射地址,如::ffff:192.0.2.1
。若是启用此选项,该地址将解压缩到192.0.2.1
。默认值为禁用。只能在protocol
设置为'both'时使用。
.
[]
(空list)
字符串列表
给定值列表中的每一个值是否存在于选项列表中。
required
, invalid_choice
, invalid_list
invalid_choice错误信息可能包含%(value)s,它将被选定的选项替换。
相对ChoiceField
来讲该参数在这里是必选的。
empty_value
由coerce参数决定
给定值是否存在于选项列表中,并可强制执行。
required
, invalid_choice
invalid_choice错误信息可能包含%(value)s,它将被选定的选项替换。
None
False、True或None。
任何内容(即,它从不引起ValidationError
)。
''
(空字符串)
字符串。
给定值是否与某个正则表达式匹配。
required
, invalid
指定为字符串类型正则表达式或编译后的正则表达式对象。
默认为False
。若是启用,将在regex验证以前去除先后空格。
''
(空字符串)
字符串。
给定的值只包含字母、数字、下划线和连字符。
required
, invalid
指示字段除接受ASCII字母以外还接受Unicode字母的布尔值,默认为False。
参数说明
None
datetime.time
给定值是否为datetime.time
或以特定时间格式化的字符串。
required
, invalid
用于尝试将字符串转换为datetime.time
对象的有效的格式的列表。
若是没有input_formats参数,默认输入格式以下:
'%H:%M:%S', # '14:30:59' '%H:%M', # '14:30'
''
(空字符串)
字符串
给定值是否为有效URL。
required
, invalid
控制输入长度范围。
from django.db import models class UserInfo(models.Model): name =models.CharField(max_length=32) password = models.CharField(max_length=20) age = models.IntegerField() sex = models.IntegerField(choices=((1,'男'),(0,'女')))
from django import forms from app import models class UserForm(forms.ModelForm): class Meta: model = models.UserInfo fields = '__all__' labels = { "name": "用户名", "sex": "性别", 'age':'年龄', 'password':'密码' } widgets = { "password": forms.widgets.PasswordInput(attrs={"class": "c1"}), }
ModelForm类中Meta类下经常使用字段说明:
model = models.UserInfo # 对应的Model中的类 fields = "__all__" # 字段,若是是__all__,就是表示列出全部的字段,也能够是一个须要渲染的字段名列表。 exclude = None # 排除的字段 labels = None # 提示信息 help_texts = None # 帮助提示信息 widgets = None # 自定义插件 error_messages = None # 自定义错误信息
from django import forms class CommentForm(forms.Form): comment = forms.CharField(widget=forms.Textarea)效果:
class SimpleForm(forms.Form): birth_year = forms.DateField(widget=forms.SelectDateWidget(years=('1980', '1981', '1982')))效果:
from django import forms class SimpleForm(forms.Form): favorite_colors = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple, choices=( ('blue', 'Blue'), ('green', 'Green'), ('black', 'Black'), ) )效果:
from django import forms class SimpleForm(forms.Form): choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=(('1', 'First',), ('2', 'Second',)))效果:
from django import forms class SimpleForm(forms.Form): # CharField字段默认小部件就是TextInput,因此指定和不指定的效果是同样的。 name = forms.CharField(widget=forms.TextInput())效果:
from django import forms class SimpleForm(forms.Form): hobby = forms.fields.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=3, widget=forms.widgets.Select() )效果:
from django import forms class SimpleForm(forms.Form): hobby = forms.fields.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple() )效果:
单选勾选框。
from django import forms class SimpleForm(forms.Form): keep = forms.fields.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput() )效果:
能够经过attrs来给小部件指定展现时的属性:
from django import forms name = forms.TextInput(attrs={'size': 10, 'title': 'Your name'}) name.render('name', 'A name') '<input title="Your name" type="text" name="name" value="A name" size="10" />'
可经过重写form类的__init__方法实现。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用户名", initial="张三", error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短8位" } ... def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) for field in iter(self.fields): self.fields[field].widget.attrs.update({ 'class': 'form-control' })