表单1
HTML表单概述
Django开发的是动态Web服务,而非单纯提供静态页面。动态服务的本质在于和用户进行互动,接收用户的输入,根据输入的不同,返回不同的内容给用户。返回数据是我们服务器后端做的,而接收用户输入就需要靠HTML表单。表单...
可以收集其内部标签中的用户输入,然后将数据发送到服务端。
一个HTML表单必须指定两样东西:
- 目的地:用户数据发送的目的URL
- 方式:发送数据所使用的HTTP方法
例如,Django Admin站点的登录表单包含几个元素:type="text"
用于用户名,type="password"
用于密码,type="submit"
用于“登录"按钮。它还包含一些用户看不到的隐藏的文本字段,Django 使用它们来提高安全性和决定下一步的行为。它还告诉浏览器表单数据应该发往的action属性指定的URL:/admin/
,而且应该使用method属性指定的HTTP post方法发送数据。当点击元素时,数据将发送给/admin/
。
其HTML源码如下:
<form action="/admin/login/?next=/admin/" method="post" id="login-form">
<input type='hidden' name='csrfmiddlewaretoken' value='NNHZaDVJGduajNMECXygKZkAt8vyEcw9HS2qm2Vdf7brDZrA0qK1R0I7M2p3TKcs' />
<div class="form-row">
<label class="required" for="id_username">用户名:</label>
<input type="text" name="username" autofocus maxlength="254" required id="id_username" />
</div>
<div class="form-row">
<label class="required" for="id_password">密码:</label>
<input type="password" name="password" required id="id_password" />
<input type="hidden" name="next" value="/admin/" />
</div>
<div class="submit-row">
<label> </label><input type="submit" value="登录" />
</div>
</form>
GET和POST :
处理表单时候只会用到POST和GET方法。
GET方法将用户数据以键=值
的形式,以‘&’符号组合在一起成为一个整体字符串,最后添加前缀“?”,将字符串拼接到url内,生成一个类似https://docs.djangoproject.com/search/?q=forms&release=1
的URL。
而对于POST方法,浏览器会组合表单数据、对它们进行编码,然后打包将它们发送到服务器,数据不会出现在url中。
GET方法通常用来请求数据,不适合密码表单这一类保密信息的发送,也不适合数据量大的表单和二进制数据。对于这些类型的数据,应该使用POST方法。但是,GET特别适合网页搜索的表单,因为这种表示一个GET请求的URL可以很容易地设置书签、分享和重新提交。
Django的form表单
通常情况下,我们需要自己手动在HTML页面中,编写form标签和其内的其它元素。但这费时费力,而且有可能写得不太恰当,数据验证也比较麻烦。有鉴于此,Django在内部集成了一个表单模块,专门帮助我们快速处理表单相关的内容。Django的表单模块给我们提供了下面三个主要功能:
- 准备和重构数据用于页面渲染,生成页面可用的HTML标签。
- 为数据创建HTML表单元;并且可以保留上次输入内容
- 接收和处理用户从表单发送过来的数据,对用户提交的数据进行校验。
编写Django的form表单,非常类似在模型系统里编写一个模型。在模型中,一个字段代表数据表的一列,而form表单中的一个字段代表中的一个元素。
使用表单
假设想从表单接收用户名数据,一般情况下,你需要在HTML中手动编写一个如下的注册功能表单元素:
<body>
<form action="/reg/" method="post">
{% csrf_token %}
<p>
用户名:
<input type="text" name="name">
</p>
<p>
密码:
<input type="password" name="pwd">
</p>
<p>
<input type="submit" value="注册">
<p style="color: red">{{ error_msg }}</p>
</p>
</form>
</body>
可以通过Django提供的Form类来自用生成上面的表单,不再需要手动在HTML中编写。
首先,在当前app内新建一个forms.py
文件(就像views.py
,models.py
等等),然后输入下面的内容:
from django import forms
# 先定义一个RegForm类:
class RegForm(forms.Form):
name = forms.CharField(max_length=40,label="用户名") # form字段的名称写的是什么,那么前端生成input标签的时候,input标签的name属性的值就是什么
pwd = forms.CharField(label="密码")
# label用于设置说明标签
# max_length同时起到两个作用,一是在浏览器页面限制用户输入不可超过40个字符,二是在后端服务器验证用户输入的长度不可超过40。
要点:
- 导入forms模块
- 所有的表单类都要继承forms.Form类
- 每个表单字段都有自己的字段类型。比如CharField,它们分别对应一种HTML语言中的元素中的表单元素。
- 由于浏览器页面是可以被篡改、伪造、禁用、跳过的,所有的HTML手段的数据验证只能防止意外不能防止恶意行为,是没有安全保证的,破坏分子完全可以跳过浏览器的防御手段伪造发送请求。所以,在服务器后端,必须进行完全彻底的数据验证和安全防护。
每个Django表单的实例都有一个内置的is_valid()
方法,用来验证接收的数据是否合法。如果所有数据都合法,那么该方法将返回True。from表单会将合法的表单数据转存到form.cleaned_data
的属性中,该属性是一个字典类型数据,可以运用字典的方法进行取值。
Django的表单模块内置了许多表单字段,每一个表单字段类型都对应一种Widget类,每一种Widget类都对应了HMTL语言中的一种input元素类型。
视图处理
需要在视图中,实例化我们编写好的表单类。
# views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import RegForm
# 使用form组件实现注册方式
def register(request):
# 如果form通过POST方法发送数据,接收表单数据,并验证
if request.method == "POST":
# 接受request.POST参数构造form类的实例
form_obj = RegForm(data=request.POST) #传过来的input标签的name属性值和form类对应的字段名是一样的,所以接过来后,form就取出对应的form字段名相同的数据进行form校验
# 验证数据是否合法,如果数据合法,按照正常业务逻辑继续执行下去
if form_obj.is_valid():
name = form.cleaned_data('name')
pwd = form.cleaned_data('pwd')
return HttpResponse("注册成功")
# 如果不合法,返回一个自动包含先前数据的表单给前端页面,方便用户修改。
# 如果是通过GET方法请求数据,返回一个空的表单,让用户可以填入数据
else:
form_obj = RegForm()
return render(request, "register.html", {"form_obj": form_obj})
要点是:
- 对于GET方法请求页面时,返回空的表单,让用户可以填入数据;
- 对于POST方法,接收表单数据,并验证;
- 如果数据合法,按照正常业务逻辑继续执行下去;
通过表单的is_bound
属性可以获知一个表单已经绑定了数据,还是一个空表。
模板处理
在Django的模板中,我们只需要按下面处理,就可以得到完整的HTML页面:
<body>
<form action="/reg2/" method="post" novalidate autocomplete="off"> #novalidate 让浏览器不要对输入的内容做校验
{% csrf_token %}
<div>
<label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
{{ form_obj.name }} {{ form_obj.name.errors.0 }} # errors是这个字段所有的错误,是ul标签;用第一个错误errors.0,是错误文本
{{ form_obj.errors }} # 这是全局的所有错误,找对应字段的错误,就要form_obj.字段名
</div>
<div>
<label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
{{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
</div>
<div>
<input type="submit" class="btn btn-success" value="注册">
</div>
</form>
</body>
要点:
- 标签要自己写,表单实例字段的属性不包含标签本身以及提交按钮,因此方便控制表单动作和CSS,JS以及其它类似bootstrap框架的嵌入。
- 使用POST的方法时,必须添加
{% csrf_token %}
标签,用于处理csrf安全机制; - 提交按钮需要手动添加。
提示:默认情况下,Django支持HTML5的表单验证功能,比如邮箱地址验证、必填项目验证等等。
Django表单内置常用字段与插件
创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML。
以下的参数是每个Field类都可以使用的。
required=True, 是否允许为空
widget=None, HTML插件
label=None, 用于生成Label标签或显示内容
label_suffix=None Label内容后缀
initial=None, 初始值
help_text='', 帮助信息(在标签旁边显示)
error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'}
validators=[], 自定义验证规则
localize=False, 是否支持本地化
disabled=False, 是否可以编辑
1.required
默认required=True,若要表示一个字段不是必需的,设置required=False。
2. label
用于生成Label标签或显示内容。例子:
>>> from django import forms
>>> class CommentForm(forms.Form):
... name = forms.CharField(label='Your name')
... url = forms.URLField(label='Your website', required=False)
... comment = forms.CharField()
>>> f = CommentForm(auto_id=False)
>>> print(f)
<tr><th>Your name:</th><td><input type="text" name="name" required /></td></tr>
<tr><th>Your website:</th><td><input type="url" name="url" /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" required /></td></tr>
3. label_suffix
Django默认为上面的label参数后面加个冒号后缀,如果想自定义,可以使用label_suffix
参数。比如下面的例子用“?”代替了冒号:
>>> class ContactForm(forms.Form):
... age = forms.IntegerField()
... nationality = forms.CharField()
... captcha_answer = forms.IntegerField(label='2 + 2', label_suffix=' =')
>>> f = ContactForm(label_suffix='?')
>>> print(f.as_p())
<p><label for="id_age">Age?</label> <input id="id_age" name="age" type="number" required /></p>
<p><label for="id_nationality">Nationality?</label> <input id="id_nationality" name="nationality" type="text" required /></p>
<p><label for="id_captcha_answer">2 + 2 =</label> <input id="id_captcha_answer" name="captcha_answer" type="number" required /></p>
4. initial
如果渲染表单的时候传递一个包含初始化值的字典给它,将触发表单的验证过程,此时输出的HTML页面将包含验证中产生的错误,如下所示:
>>> class CommentForm(forms.Form):
... name = forms.CharField()
... url = forms.URLField()
... comment = forms.CharField()
>>> default_data = {'name': 'Your name', 'url': 'http://'}
>>> f = CommentForm(default_data, auto_id=False)
>>> print(f)
<tr><th>Name:</th><td><input type="text" name="name" value="Your name" required /></td></tr>
<tr><th>Url:</th><td><ul class="errorlist"><li>Enter a valid URL.</li></ul><input type="url" name="url" value="http://" required /></td></tr>
<tr><th>Comment:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="comment" required /></td></tr>
initial参数只用在未绑定的表单上。为HTML页面中表单元素定义初始值。也就是input元素的value参数的值。
还要注意,如果提交表单时某个字段的值没有填写,initial的值不会作为“默认”的数据。initial值只用于原始表单的显示:
>>> class CommentForm(forms.Form):
... name = forms.CharField(initial='Your name')
... url = forms.URLField(initial='http://')
... comment = forms.CharField()
>>> data = {'name': '', 'url': '', 'comment': 'Foo'}
>>> f = CommentForm(data)
>>> f.is_valid()
False
# The form does *not* fall back to using the initial values.
>>> f.errors
{'url': ['This field is required.'], 'name': ['This field is required.']}
除了常量之外,还可以传递一个可调用的对象:
>>> import datetime
>>> class DateForm(forms.Form):
... day = forms.DateField(initial=datetime.date.today)
>>> print(DateForm())
<tr><th>Day:</th><td><input type="text" name="day" value="12/23/2008" required /><td></tr>
5. help_text
该参数用于设置字段的辅助描述文本。
>>> from django import forms
>>> class HelpTextContactForm(forms.Form):
... sender = forms.EmailField(help_text='A valid email address, please.')
... cc_myself = forms.BooleanField(required=False)
>>> f = HelpTextContactForm(auto_id=False)
>>> print(f.as_table())
<tr>
<th>Sender:</th>
<td><input type="email" name="sender" required/><br/>A valid email address, please.</td>
</tr>
<tr>
<th>Cc myself:</th>
<td><input type="checkbox" name="cc_myself"/></td>
</tr>
>>> print(f.as_ul())
<li>Sender: <input type="email" name="sender" required/> A valid email address, please.</li>
<li>Cc myself: <input type="checkbox" name="cc_myself"/></li>
>>> print(f.as_p())
<p>Sender: <input type="email" name="sender" required/> A valid email address, please.</p>
<p>Cc myself: <input type="checkbox" name="cc_myself"/></p>
6. error_messages
该参数允许你覆盖字段引发异常时的默认信息。 传递的是一个字典,其键为你想覆盖的错误信息。 例如自定义的错误信息:
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="密码")
可以指定多种类型的键,不仅仅针对‘requeired’错误。
7. validators
指定一个列表,其中包含了为字段进行验证的函数。也就是说,如果你自定义了验证方法,不用Django内置的验证功能,那么要通过这个参数,将字段和自定义的验证方法链接起来。
8. localize
localize参数帮助实现表单数据输入的本地化。
9. disabled
设置有该属性的字段在前端页面中将显示为不可编辑状态。
该参数接收布尔值,当设置为True时,使用HTML的disabled属性禁用表单域,以使用户无法编辑该字段。即使非法篡改了前端页面的属性,向服务器提交了该字段的值,也将依然被忽略。
10. widget
指定渲染Widget时使用的widget类,也就是这个form字段在HTML页面中是显示为文本输入框、密码输入框、单选按钮、多选框还是别的。
表单字段负责验证输入并直接在模板中使用。而Widget负责渲染网页上HTML表单的输入元素和提取提交的原始数据。widget是字段的一个内在属性,用于定义字段在浏览器的页面里以何种HTML元素展现。
指定使用的widget
每个字段都有一个默认的widget类型。如果想要使用一个不同的Widget,可以在定义字段时使用widget参数。 像这样:
from django import forms
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
这将使用一个Textarea Widget来展现表单的评论字段,而不是默认的TextInput Widget。
设置widget的参数
许多widget具有可选的额外参数,下面的示例中,设置了SelectDateWidget
的years属性:
from django import forms
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
FAVORITE_COLORS_CHOICES = (
('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'),
)
class SimpleForm(forms.Form):
birth_year = forms.DateField(widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES))
favorite_colors = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple,
choices=FAVORITE_COLORS_CHOICES,
)
为widget添加CSS样式
默认情况下,当Django渲染Widget为实际的HTML代码时,不添加任何的CSS样式,也就是说网页上所有的TextInput元素的外观是一样的。
可以在创建Widget时使用Widget.attrs
参数来实现添加CSS样式目的:
class CommentForm(forms.Form):
name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
url = forms.URLField()
comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))
渲染后的结果:
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special" required /></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40" required /></td></tr>
PasswordInput
class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True) #这个密码字段和其他字段不一样,默认在前端输入数据错误的时候,点击提交之后,默认是不保存的原来数据,但是可以通过render_value=True让这个字段在前端保留用户输入的数据
)
radioSelect:单radio值为字符串
class LoginForm(forms.Form):
username = forms.CharField( # 其他选择框或者输入框,基本都是在这个CharField的基础上通过插件来设置的
min_length=8,
label="用户名",
initial="haha",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
单选Select
class LoginForm(forms.Form):
...
hobby = forms.fields.ChoiceField( # 注意,单选框用的是ChoiceField,并且里面的插件是Select,不然验证的时候会报Select a valid choice的错误。
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
多选Select
class LoginForm(forms.Form):
...
hobby = forms.fields.MultipleChoiceField( #多 选框的时候用MultipleChoiceField,并且里面的插件用的是SelectMultiple,不然验证的时候会报错。
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
单选checkbox
class LoginForm(forms.Form):
...
keep = forms.fields.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
多选checkbox
class LoginForm(forms.Form):
...
hobby = forms.fields.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
date类型
from django import forms
from django.forms import widgets
class BookForm(forms.Form):
date = forms.DateField(widget=widgets.TextInput(attrs={'type':'date'})) #必须指定type,不然不能渲染成选择时间的input框 .
choice字段注意事项
在使用选择标签时,需要注意choices的选项可以配置从数据库中获取,但是由于是静态字段 获取的值无法实时更新,需要重写构造方法从而实现choice实时更新。
方式一:
from django.forms import Form
from django.forms import widgets
from django.forms import fields
class MyForm(Form):
user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
initial=2,
widget=widgets.Select
)
def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs) # 注意重写init方法的时候,*args和**kwargs一定要写上,不然会出问题,并且验证总是不能通过,还不显示报错信息
# self.fields['user'].choices = ((1, '上海'), (2, '北京'),)
# 或
self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')
方式二:
from django import forms
from django.forms import fields
from django.forms import models as form_model
class FInfo(forms.Form):
authors = forms.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多选,或者下面这种方式,通过forms里面的models中提供的方法也是一样的。
authors = forms.models.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多选
#authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 单选 #或者,forms.ModelChoiceField(queryset=models.Publisth.objects.all(),widget=forms.widgets.Select()) 单选 #
authors = forms.ModelMultipleChoiceField( queryset=models.Author.objects.all(), widget = forms.widgets.Select(attrs={'class': 'form-control'} ))
# 如果用这种方式,别忘了model表中,NNEWType的__str__方法要写上,不然选择框里将会是object对象
Form所有内置字段
对于下面每个字段类介绍其默认的widget,当输入为空时返回的值,以及采取何种验证方式。
规范化为表示转换为Python的何种对象。可用的错误信息键,表示该字段可自定义错误信息的类型(字典的键)。
1.CharField
- 默认的Widget:TextInput
- 空值:与empty_value给出的任何值。
- 规范化为:一个Unicode 对象。
- 验证
max_length
或min_length
,如果设置了这两个参数。 否则,所有的输入都是合法的。 - 可用的错误信息键:min_length, max_length, required
有四个可选参数:
- max_length,min_length:设置字符串的最大和最小长度。
- strip:如果True(默认),去除输入的前导和尾随空格。
- empty_value:用来表示“空”的值。 默认为空字符串。
2.IntegerField
- 默认的Widget:当Field.localize是False时为NumberInput,否则为TextInput。
- 空值:None
- 规范化为:Python 整数或长整数。
- 验证给定值是一个整数。 允许前导和尾随空格,类似Python的int()函数。
- 错误信息的键:max_value, invalid, required, min_value
两个可选参数:max_value和min_value,控制允许的值的范围。
3.FloatField
- 默认的Widget:当Field.localize是False时为NumberInput,否则为TextInput。
- 空值:None
- 规范化为:Float 对象。
- 验证给定的值是一个浮点数。
- 错误信息的键:max_value, invalid, required, min_value
接收两个可选的参数用于验证,max_value和min_value,控制允许的值的范围。
4.DecimalField
- 默认的Widget:当Field.localize是False时为NumberInput,否则为TextInput。
- 空值:None
- 规范化为:Python decimal对象。
- 验证给定的值为一个十进制数。 忽略前导和尾随的空白。
- 错误信息的键:
max_whole_digits
,max_digits
,max_decimal_places
,max_value
,invalid
,required
,min_value
接收四个可选的参数:
max_value,min_value:允许的值的范围,需要赋值decimal.Decimal对象,不能直接给个整数类型。
max_digits:值允许的最大位数(小数点之前和之后的数字总共的位数,前导的零将被删除)。
decimal_places:允许的最大小数位。
5.DateField
- 默认的Widget:DateInput
- 空值:None
- 规范化为:datetime.date对象。
- 验证给出的值是一个datetime.date、datetime.datetime 或指定日期格式的字符串。
- 错误信息的键:required, invalid
接收一个可选的参数:input_formats。一个格式的列表,用于转换字符串为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'
6. DateTimeField
- 默认的Widget:DateTimeInput
- 空值:None
- 规范化为:Python的datetime.datetime对象。
- 验证给出的值是一个datetime.datetime、datetime.date或指定日期格式的字符串。
- 错误信息的键:required, invalid
接收一个可选的参数:input_formats
如果没有提供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'
7.TimeField
- 默认的Widget:TextInput
- 空值:None
- 规范化为:一个Python 的datetime.time 对象。
- 验证给定值是datetime.time或以特定时间格式格式化的字符串。
- 错误信息的键:required, invalid
接收一个可选的参数:input_formats,用于尝试将字符串转换为有效的datetime.time对象的格式列表。
如果没有提供input_formats,默认的输入格式为:
'%H:%M:%S', # '14:30:59'
'%H:%M', # '14:30'
8. DurationField
- 默认的Widget:TextInput
- 空值:None
- 规范化为:Python timedelta。
- 验证给出的值是一个字符串,而且可以转换为timedelta对象。
- 错误信息的键:required, invalid.
- 时间间隔:%d %H:%M:%S.%f
9.RegexField
- 默认的Widget:TextInput
- 空值:''(一个空字符串)
- 规范化为:一个Unicode 对象。
- 验证给定值与某个正则表达式匹配。
- 错误信息的键:required, invalid
需要一个必需的参数:regex,需要匹配的正则表达式。
还可以接收max_length,min_length和strip参数,类似CharField。
9. EmailField
- 默认的Widget:EmailInput
- 空值:''(一个空字符串)
- 规范化为:Unicode 对象。
- 使用正则表达式验证给出的值是一个合法的邮件地址。
- 错误信息的键:required, invalid
两个可选的参数用于验证,max_length 和min_length。
10. FileField
- 默认的Widget:ClearableFileInput
- 空值:None
- 规范化为:一个UploadedFile对象,它封装文件内容和文件名到一个对象内。
- 验证非空的文件数据已经绑定到表单。
- 错误信息的键:missing, invalid, required, empty, max_length
具有两个可选的参数用于验证:max_length 和 allow_empty_file。
11. FilePathField
- 默认的Widget:Select
- 空值:None
- 规范化为:Unicode 对象。
- 验证选择的选项在选项列表中存在。
- 错误信息的键:required, invalid_choice
这个字段允许从一个特定的目录选择文件。 它有五个额外的参数,其中的path是必须的:
path:要列出的目录的绝对路径。 这个目录必须存在。
recursive:如果为False(默认值),只用直接位于path下的文件或目录作为选项。如果为True,将递归访问这个目录,其内所有的子目录和文件都将作为选项。
match:正则表达模式;只有具有与此表达式匹配的文件名称才被允许作为选项。
allow_files
:可选。默认为True。表示是否应该包含指定位置的文件。它和allow_folders
必须有一个为True。
allow_folders
可选。默认为False。表示是否应该包含指定位置的目录。
FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
required=True,
widget=None,
label=None,
13. ImageField
- 默认的Widget:ClearableFileInput
- 空值:None
- 规范化为:一个UploadedFile 象,它封装文件内容和文件名为一个单独的对象。
- 验证文件数据已绑定到表单,并且该文件是Pillow可以解析的图像格式。
- 错误信息的键:missing, invalid, required, empty, invalid_image
使用ImageField需要安装Pillow(pip install pillow)。如果在上传图片时遇到图像损坏错误,通常意味着使用了Pillow不支持的格式。
以上两个字典使用时,需要注意两点:
- form表单中 enctype="multipart/form-data"
- view函数中 obj = MyForm(request.POST, request.FILES)
14. URLField
- 默认的Widget:URLInput
- 空值:''(一个空字符串)
- 规范化为:一个Unicode 对象。
- 验证给定值是个有效的URL。
- 错误信息的键:required, invalid
可选参数:max_length和min_length
15. BooleanField
- 默认的Widget:CheckboxInput
- 空值:False
- 规范化为:Python的True或者False
- 可用的错误信息键:required
16. NullBooleanField
- 默认的Widget:NullBooleanSelect
- 空值:None
- 规范化为:Python None, False 或True 值。
- 不验证任何内容(即,它从不引发ValidationError)。
17. ChoiceField
- 默认的Widget:Select
- 空值:''(一个空字符串)
- 规范化为:一个Unicode 对象。
- 验证给定的值是否在选项列表中。
- 可用的错误信息键:required, invalid_choice
参数choices:用来作为该字段选项的一个二元组组成的可迭代对象(例如,列表或元组)或者一个可调用对象。格式与用于和ORM模型字段的choices参数相同。
18. TypedChoiceField
像ChoiceField一样,只是还有两个额外的参数:coerce和empty_value。
- 默认的Widget:Select
- 空值:empty_value参数设置的值。
- 规范化为:coerce参数类型的值。
- 验证给定的值在选项列表中存在并且可以被强制转换。
- 可用的错误信息的键:required, invalid_choice
19. MultipleChoiceField
- 默认的Widget:SelectMultiple
- 空值:[](一个空列表)
- 规范化为:一个Unicode 对象列表。
- 验证给定值列表中的每个值都存在于选择列表中。
- 错误信息的键:invalid_list, invalid_choice, required
20. TypedMultipleChoiceField
类似MultipleChoiceField,除了需要两个额外的参数,coerce和empty_value。
- 默认的Widget:SelectMultiple
- 空值:empty_value
- 规范化为:coerce参数提供的类型值列表。
- 验证给定值存在于选项列表中并且可以强制。
- 错误信息的键:required, invalid_choice
coerce = lambda val: val 对选中的值进行一次转换
21. SlugField
- 默认的Widget:TextInput
- 空值:''(一个空字符串)
- 规范化为:一个Unicode 对象。
- 验证给定的字符串只包括字母、数字、下划线及连字符。
- 错误信息的键:required, invalid
此字段用于在表单中表示模型的SlugField。
22. ComboField
- 默认的Widget:TextInput
- 空值:''(一个空字符串)
- 规范化为:Unicode 对象。
- 根据指定为ComboField的参数的每个字段验证给定值。
- 错误信息的键:required, invalid
接收一个额外的必选参数:fields,用于验证字段值的字段列表(按提供它们的顺序)。
>>> from django.forms import ComboField
>>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
>>> f.clean('test@example.com')
'test@example.com'
>>> f.clean('longemailaddress@example.com')
Traceback (most recent call last):
...
ValidationError: ['Ensure this value has at most 20 characters (it has 28).']
23. MultiValueField
- 默认的Widget:TextInput
- 空值:''(一个空字符串)
- 规范化为:子类的compress方法返回的类型。
- 根据指定为MultiValueField的参数的每个字段验证给定值。
- 错误信息的键:incomplete, invalid, required
抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
24. GenericIPAddressField
包含IPv4或IPv6地址的字段。
- 默认的Widget:TextInput
- 空值:''(一个空字符串)
- 规范化为:一个Unicode对象。
- 验证给定值是有效的IP地址。
- 错误信息的键:required, invalid
有两个可选参数:protocol和unpack_ipv4
protocol='both', both,ipv4,ipv6支持的IP格式
unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1,protocol必须为both才能启
25. SplitDateTimeField
- 默认的Widget:SplitDateTimeWidget
- 空值:None
- 规范化为:Python datetime.datetime 对象。
- 验证给定的值是datetime.datetime或以特定日期时间格式格式化的字符串。
- 错误信息的键:invalid_date, invalid, required, invalid_time
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']
26. UUIDField
- 默认的Widget:TextInput
- 空值:''(一个空字符串)
- 规范化为:UUID对象。
- 错误信息的键:required, invalid
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
创建自定义字段
自定义Field只需要创建一个django.forms.Field
的子类,并实现clean()和__init__()
构造方法。__init__()
构造方法需要接收前面提过的那些核心参数,比如widget、required,、label、help_text、initial。
还可以通过覆盖get_bound_field()
方法来自定义访问字段的方式。