django 1.8 官方文档翻译:5-1-2 表单API
表单 API
关于这篇文档
这篇文档讲述Django 表单API 的详细细节。你应该先阅读_表单简介_。 如果是绑定的,那么它能够验证数据,并渲染表单及其数据成HTML。 如果是未绑定的,那么它不能够完成验证(因为没有可验证的数据!),但是仍然能渲染空白的表单成HTML。 _class _ 若要创建一个未绑定的 若要绑定数据到表单,可以将数据以字典的形式传递给 在这个字典中,键为字段的名称,它们对应于 如果运行时刻你需要区分绑定的表单和未绑定的表单,可以检查下表单 注意,传递一个空的字典将创建一个带有空数据的_绑定的_表单: 如果你有一个绑定的 当你需要为相互依赖的字段添加自定义的验证时,你可以实现 让我们试下非法的数据。下面的情形中, 访问 在这个字典中,键为字段的名称,值为表示错误信息的Unicode 字符串组成的列表。错误信息保存在列表中是因为字段可能有多个错误信息。 你可以在调用 验证将值调用一次,无论你访问 New in Django 1.7\. 返回一个 每当你需要根据错误的 需要 New in Django 1.7\. 返回JSON 序列化后的错误。 默认情况下, 如果由于某种原因你不想使用客户端的转义,你还可以设置 New in Django 1.7\. 这个方法允许在 注意, New in Django 1.8\. 这个方法返回一个布尔值,指示一个字段是否具有指定错误 若要检查非字段错误,使用 这个方法返回 验证没有绑定数据的表单是没有意义的,下面的例子展示了这种情况: 表单字段的初始值使用 使用 这些值只显示在没有绑定的表单中,即使没有提供特定值它们也不会作为后备的值。 注意,如果 当你需要检查表单的数据是否从初始数据发生改变时,可以使用 当提交表单时,我们可以重新构建表单并提供初始值,这样可以实现比较: 如果 你可以从 可你可以修改 注意不要改变 例如, 一旦你创建一个 注意,文本字段 —— 例如, 如果你的数据_没有_ 通过验证, 当 在上面的例子中, 你可以自己编写代码来对特定的字段(根据它们的名字)或者表单整体(考虑到不同字段的组合)进行验证。更多信息参见_表单和字段验证_。 如果表单是绑定的,输出的HTML 将包含数据。例如,如果字段是 默认的输出时具有两个列的HTML 表格,每个字段对应一个 为了灵活性,输出_不_包含 每个字段类型有一个默认的HTML 表示。 每个标签的HTML 每个字段的文本标签 —— 例如 每个文本标签周围有一个HTML 虽然 最后, 将必填的表单行和有错误的表单行定义不同的样式特别常见。例如,你想将必填的表单行以粗体显示、将错误以红色显示。 一旦你设置好,将根据需要设置行的 Changed in Django 1.8: 默认情况下,表单的渲染方法包含: 表单元素的HTML 对应的 如果 如果 如果 如果 默认情况下, 一个字符串(默认为英文的 使用 注意,该标签后缀只有当label 的最后一个字符不是表单符号( New in Django 1.8\. 字段可以定义自己的 在 如果你渲染一个绑定的 默认情况下,表单使用 Changed in Django 1.7: _class _ 用于显示HTML 表单或者访问 其 以字段的名称为键,用字典查询语法查询表单,可以获取一个 迭代表单可以获取所有的 字段的输出与表单的 若要获取字段的错误列表,可以访问字段的 一个类列表对象,打印时以HTML 可以调用 如果你提供一个可选的 生成的HTML 包含表单的 Changed in Django 1.8: 如果可用,label 将包含 当你使用Django 的快捷的渲染方法时,习惯使用CSS ?类型来表示必填的表单字段和有错误的字段。如果你是手工渲染一个表单,你可以使用 除了错误和必填的类型之外,如果你还想提供额外的类型,你可以用参数传递它们: 这个方法用于渲染字段的原始值,与用 使用这个属性渲染字段的ID。例如,如果你在模板中手工构造一个绑定的表单和未绑定的表单
表单
要么是绑定的,要么是未绑定的。Form
表单
实例,只需简单地实例化该类:>>> f = ContactForm()
表单
类的构造函数的第一个参数:>>> data = {'subject': 'hello',... 'message': 'Hi there',... 'sender': 'foo@example.com',... 'cc_myself': True}>>> f = ContactForm(data)
表单
类中的属性。值为需要验证的数据。它们通常为字符串,但是没有强制要求必须是字符串;传递的数据类型取决于字段
,我们稍后会看到。Form.
`is_bound`is_bound
属性的值:>>> f = ContactForm()>>> f.is_boundFalse>>> f = ContactForm({'subject': 'hello'})>>> f.is_boundTrue
>>> f = ContactForm({})>>> f.is_boundTrue
表单
实例但是想改下数据,或者你想绑定一个未绑定的表单
表单到某些数据,你需要创建另外一个表单
实例。Form
实例的数据没有办法修改。表单
实例一旦创建,你应该将它的数据视为不可变的,无论它有没有数据。使用表单来验证数据
Form.
`clean`()表单
的clean()
方法。示例用法参见_Cleaning and validating fields that depend on each other_。Form.
`is_valid`()表单
对象的首要任务就是验证数据。对于绑定的表单
实例,可以调用is_valid()
方法来执行验证并返回一个表示数据是否合法的布尔值。>>> data = {'subject': 'hello',... 'message': 'Hi there',... 'sender': 'foo@example.com',... 'cc_myself': True}>>> f = ContactForm(data)>>> f.is_valid()True
subject
为空(默认所有字段都是必需的)且sender
是一个不合法的邮件地址:>>> data = {'subject': '',... 'message': 'Hi there',... 'sender': 'invalid email address',... 'cc_myself': True}>>> f = ContactForm(data)>>> f.is_valid()False
Form.
`errors`errors
属性可以获得错误信息的一个字典:>>> f.errors{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
is_valid()
?之前访问errors
。表单的数据将在第一次调用is_valid()
或者访问errors
时验证。errors
或者调用is_valid()
多少次。这意味着,如果验证过程有副作用,这些副作用将只触发一次。Form.errors.
`as_data`()字典
,它映射字段到原始的ValidationError
实例。>>> f.errors.as_data(){'sender': [ValidationError(['Enter a valid email address.'])],'subject': [ValidationError(['This field is required.'])]}
code
来识别错误时,可以调用这个方法。它可以用来重写错误信息或者根据特定的错误编写自定义的逻辑。它还可以用来序列化错误为一个自定义的格式(例如,XML);as_json()
就依赖于as_data()
。as_data()
方法是为了向后兼容。以前,ValidationError
实例在它们渲染后?的错误消息一旦添加到Form.errors
字典就立即被丢弃。理想情况下,Form.errors
应该已经保存ValidationError
实例而带有as_
前缀的方法可以渲染它们,但是为了不破坏直接使用Form.errors
中的错误消息的代码,必须使用其它方法来实现。Form.errors.
`as_json`(_escape_html=False_)>>> f.errors.as_json(){"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],"subject": [{"message": "This field is required.", "code": "required"}]}
as_json()
不会转义它的输出。如果你正在使用AJAX 请求表单视图,而客户端会解析响应并将错误插入到页面中,你必须在客户端对结果进行转义以避免可能的跨站脚本攻击。使用一个JavaScript 库比如jQuery 来做这件事很简单 —— 只要使用$(el).text(errorText)
而不是.html()
就可以。escape_html=True
,这样错误消息将被转义而你可以直接在HTML 中使用它们。Form.
`add_error`(_field_, _error_)Form.clean()
方法内部或从表单的外部一起给字段添加错误信息;例如从一个视图中。field
参数为字段的名称。如果值为None
,error 将作为Form.non_field_errors()
返回的一个非字段错误。error
参数可以是一个简单的字符串,或者最好是一个ValidationError
实例。_引发ValidationError_ 中可以看到定义表单错误时的最佳实践。Form.add_error()
会自动删除cleaned_data
中的相关字段。Form.
`has_error`(_field_, _code=None_)code
的错误。当code
为None
时,如果字段有任何错误它都将返回True
。NON_FIELD_ERRORS
作为field
参数。Form.
`non_field_errors`()Form.errors
中不是与特定字段相关联的错误。它包含在Form.clean()
中引发的ValidationError
和使用Form.add_error(None, "...")
添加的错误。未绑定表单的行为
>>> f = ContactForm()>>> f.is_valid()False>>> f.errors{}
动态的初始值
Form.
`initial`initial
声明。例如,你可能希望使用当前会话的用户名填充username
字段。Form
的initial
参数可以实现。该参数是字段名到初始值的一个字典。只需要包含你期望给出初始值的字段;不需要包含表单中的所有字段。例如:>>> f = ContactForm(initial={'subject': 'Hi there!'})
字段
有定义initial
, _而_实例化表单
时也提供initial
,那么后面的initial
将优先。在下面的例子中,initial
在字段和表单实例化中都有定义,此时后者具有优先权:>>> from django import forms>>> class CommentForm(forms.Form):... name = forms.CharField(initial='class')... url = forms.URLField()... comment = forms.CharField()>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)>>> print(f)<tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr><tr><th>Url:</th><td><input type="url" name="url" /></td></tr><tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
检查表单数据是否改变
Form.
`has_changed`()表单
的has_changed()
方法。>>> data = {'subject': 'hello',... 'message': 'Hi there',... 'sender': 'foo@example.com',... 'cc_myself': True}>>> f = ContactForm(data, initial=data)>>> f.has_changed()False
>>> f = ContactForm(request.POST, initial=data)>>> f.has_changed()
request.POST
中的数据与initial
中的不同,has_changed()
将为True
,否则为False
。 计算的结果是通过调用表单每个字段的Field.has_changed()
得到的。从表单中访问字段
Form.
`fields`表单
实例的fields
属性访问字段:>>> for row in f.fields.values(): print(row)...<django.forms.fields.CharField object at 0x7ffaac632510><django.forms.fields.URLField object at 0x7ffaac632f90><django.forms.fields.CharField object at 0x7ffaac3aa050>>>> f.fields['name']<django.forms.fields.CharField object at 0x7ffaac6324d0>
表单
实例的字段来改变字段在表单中的表示:>>> f.as_table().split('\n')[0]'<tr><th>Name:</th><td><input name="name" type="text" value="instance" /></td></tr>'>>> f.fields['name'].label = "Username">>> f.as_table().split('\n')[0]'<tr><th>Username:</th><td><input name="name" type="text" value="instance" /></td></tr>'
base_fields
属性,因为一旦修改将影响同一个Python 进程中接下来所有的ContactForm
实例:>>> f.base_fields['name'].label = "Username">>> another_f = CommentForm(auto_id=False)>>> another_f.as_table().split('\n')[0]'<tr><th>Username:</th><td><input name="name" type="text" value="class" /></td></tr>'
访问“清洁”的数据
Form.
`cleaned_data`表单
类中的每个字段不仅负责验证数据,还负责“清洁”它们 —— 将它们转换为正确的格式。这是个非常好用的功能,因为它允许字段以多种方式输入数据,并总能得到一致的输出。DateField
将输入转换为Python 的 datetime.date
对象。无论你传递的是'1994-07-15'
格式的字符串、datetime.date
对象、还是其它格式的数字,DateField
将始终将它们转换成datetime.date
对象,只要它们是合法的。表单
实例并通过验证后,你就可以通过它的cleaned_data
属性访问清洁的数据:>>> data = {'subject': 'hello',... 'message': 'Hi there',... 'sender': 'foo@example.com',... 'cc_myself': True}>>> f = ContactForm(data)>>> f.is_valid()True>>> f.cleaned_data{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}
CharField
和EmailField
—— 始终将输入转换为Unicode 字符串。我们将在这篇文档的后面将是编码的影响。cleaned_data
字典中只包含合法的字段:>>> data = {'subject': '',... 'message': 'Hi there',... 'sender': 'invalid email address',... 'cc_myself': True}>>> f = ContactForm(data)>>> f.is_valid()False>>> f.cleaned_data{'cc_myself': True, 'message': 'Hi there'}
cleaned_data
始终_只_ 包含表单
中定义的字段,即使你在构建表单
时传递了额外的数据。在下面的例子中,我们传递一组额外的字段给ContactForm
构造函数,但是cleaned_data
将只包含表单的字段:>>> data = {'subject': 'hello',... 'message': 'Hi there',... 'sender': 'foo@example.com',... 'cc_myself': True,... 'extra_field_1': 'foo',... 'extra_field_2': 'bar',... 'extra_field_3': 'baz'}>>> f = ContactForm(data)>>> f.is_valid()True>>> f.cleaned_data # Doesn't contain extra_field_1, etc.{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}
表单
合法时,cleaned_data
将包含_所有_字段的键和值,即使传递的数据不包含某些可选字段的值。在下面的例子中,传递的数据字典不包含nick_name
字段的值,但是cleaned_data
任然包含它,只是值为空:>>> from django.forms import Form>>> class OptionalPersonForm(Form):... first_name = CharField()... last_name = CharField()... nick_name = CharField(required=False)>>> data = {'first_name': 'John', 'last_name': 'Lennon'}>>> f = OptionalPersonForm(data)>>> f.is_valid()True>>> f.cleaned_data{'nick_name': '', 'first_name': 'John', 'last_name': 'Lennon'}
cleaned_data
中nick_name
设置为一个空字符串,这是因为nick_name
是CharField
而 CharField
将空值作为一个空字符串。每个字段都知道自己的“空”值 —— 例如,DateField
的空值是None
而不是一个空字符串。关于每个字段空值的完整细节,参见“内建的Field
类”一节中每个字段的“空值”提示。输出表单为HTML
表单
对象的第二个任务是将它渲染成HTML。很简单,print
它:>>> f = ContactForm()>>> print(f)<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr><tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr><tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr><tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
<input type="text">
的形式,其数据将位于value
属性中。如果字段是<input type="checkbox">
的形式,HTML 将包含checked="checked"
:>>> data = {'subject': 'hello',... 'message': 'Hi there',... 'sender': 'foo@example.com',... 'cc_myself': True}>>> f = ContactForm(data)>>> print(f)<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr><tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr><tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" value="foo@example.com" /></td></tr><tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr>
<tr>
。注意事项:<table>
和</table>
、<form>
和</form>
?以及<input type="submit">
标签。你需要添加它们。CharField
表示为一个<input type="text">
,EmailField
表示为一个<input type="email">
。BooleanField
表示为一个<input type="checkbox">
。注意,这些只是默认的表示;你可以使用Widget 指定字段使用哪种HTML,我们将稍后解释。name
直接从ContactForm
类中获取。'Subject:'
、'Message:'
和'Cc myself:'
通过将所有的下划线转换成空格并大写第一个字母生成。再次提醒,这些只是默认的表示;你可以手工指定标签。<label>
标签,它指向表单字段的id
。这个id
,是通过在字段名称前面加上'id_'
前缀生成。id
属性和<label>
标签默认包含在输出中,但你可以改变这一行为。print
表单时<table>
是默认的输出格式,但是还有其它格式可用。每个格式对应于表单对象的一个方法,每个方法都返回一个Unicode 对象。as_p()
Form.
`as_p`()as_p()
渲染表单为一系列的<p>
标签,每个<p>
标签包含一个字段:>>> f = ContactForm()>>> f.as_p()'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'>>> print(f.as_p())<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p><p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p><p><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" /></p><p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
as_ul()
Form.
`as_ul`()as_ul()
渲染表单为一系列的<li>
标签,每个<li>
标签包含一个字段。它_不_包含<ul>
和</ul>
,所以你可以自己指定<ul>
的任何HTML 属性:>>> f = ContactForm()>>> f.as_ul()'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'>>> print(f.as_ul())<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li><li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li><li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" /></li><li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
as_table()
Form.
`as_table`()as_table()
输出表单为一个HTML <table>
。它与print
完全相同。事实上,当你print
一个表单对象时,在后台调用的就是as_table()
方法:>>> f = ContactForm()>>> f.as_table()'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'>>> print(f.as_table())<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr><tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr><tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr><tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
表单必填行和错误行的样式
Form.
`error_css_class`Form.
`required_css_class`表单
类具有一对钩子,可以使用它们来添加class
属性给必填的行或有错误的行:只需简单地设置Form.error_css_class
和/或 Form.required_css_class
属性:from django.forms import Formclass ContactForm(Form): error_css_class = 'error' required_css_class = 'required' # ... and the rest of your fields here
"error"
和/或"required"
CSS 类型。 其HTML 看上去将类似:>>> f = ContactForm(data)>>> print(f.as_table())<tr class="required"><th><label class="required" for="id_subject">Subject:</label> ...<tr class="required"><th><label class="required" for="id_message">Message:</label> ...<tr class="required error"><th><label class="required" for="id_sender">Sender:</label> ...<tr><th><label for="id_cc_myself">Cc myself:<label> ...>>> f['subject'].label_tag()<label class="required" for="id_subject">Subject:</label>>>> f['subject'].label_tag(attrs={'class': 'foo'})<label for="id_subject" class="foo required">Subject:</label>
required_css_class
添加到<label>
标签,如上面所看到的。配置表单元素的HTML
id
属性和 <label>
标签Form.
`auto_id`id
属性<label>
标签。HTML <label>
标签指示标签文本关联的表单元素。这个小小的改进让表单在辅助设备上具有更高的可用性。使用<label>
标签始终是个好想法。id
属性值通过在表单字段名称的前面加上id_
生成。但是如果你想改变id
的生成方式或者完全删除 HTML id
属性和<label>
标签,这个行为是可配置的。id
和label 的行为使用表单
构造函数的auto_id
参数控制。这个参数必须为True
、False
或者一个字符串。auto_id
为False
,那么表单的输出将不包含<label>
标签和id
属性:>>> f = ContactForm(auto_id=False)>>> print(f.as_table())<tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr><tr><th>Message:</th><td><input type="text" name="message" /></td></tr><tr><th>Sender:</th><td><input type="email" name="sender" /></td></tr><tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>>>> print(f.as_ul())<li>Subject: <input type="text" name="subject" maxlength="100" /></li><li>Message: <input type="text" name="message" /></li><li>Sender: <input type="email" name="sender" /></li><li>Cc myself: <input type="checkbox" name="cc_myself" /></li>>>> print(f.as_p())<p>Subject: <input type="text" name="subject" maxlength="100" /></p><p>Message: <input type="text" name="message" /></p><p>Sender: <input type="email" name="sender" /></p><p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
auto_id
设置为True
,那么输出的表示_将_ 包含<label>
标签并简单地使用字典名称作为每个表单字段的id
:>>> f = ContactForm(auto_id=True)>>> print(f.as_table())<tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr><tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr><tr><th><label for="sender">Sender:</label></th><td><input type="email" name="sender" id="sender" /></td></tr><tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>>>> print(f.as_ul())<li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li><li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li><li><label for="sender">Sender:</label> <input type="email" name="sender" id="sender" /></li><li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>>>> print(f.as_p())<p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p><p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p><p><label for="sender">Sender:</label> <input type="email" name="sender" id="sender" /></p><p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
auto_id
设置为包含格式字符'%s'
的字符串,那么表单的输出将包含<label>
标签,并将根据格式字符串生成id
属性。例如,对于格式字符串'field_%s'
,名为subject
的字段的id
值将是'field_subject'
。继续我们的例子:>>> f = ContactForm(auto_id='id_for_%s')>>> print(f.as_table())<tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr><tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr><tr><th><label for="id_for_sender">Sender:</label></th><td><input type="email" name="sender" id="id_for_sender" /></td></tr><tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>>>> print(f.as_ul())<li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li><li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li><li><label for="id_for_sender">Sender:</label> <input type="email" name="sender" id="id_for_sender" /></li><li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>>>> print(f.as_p())<p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p><p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p><p><label for="id_for_sender">Sender:</label> <input type="email" name="sender" id="id_for_sender" /></p><p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
auto_id
设置为任何其它的真值 —— 例如不包含%s
的字符串 —— 那么其行为将类似auto_id
等于True
。auto_id
设置为'id_%s'
。Form.
`label_suffix`:
),表单渲染时将附加在每个label 名称的后面。label_suffix
参数可以自定义这个字符,或者完全删除它:>>> f = ContactForm(auto_id='id_for_%s', label_suffix='')>>> print(f.as_ul())<li><label for="id_for_subject">Subject</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li><li><label for="id_for_message">Message</label> <input type="text" name="message" id="id_for_message" /></li><li><label for="id_for_sender">Sender</label> <input type="email" name="sender" id="id_for_sender" /></li><li><label for="id_for_cc_myself">Cc myself</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>>>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->')>>> print(f.as_ul())<li><label for="id_for_subject">Subject -></label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li><li><label for="id_for_message">Message -></label> <input type="text" name="message" id="id_for_message" /></li><li><label for="id_for_sender">Sender -></label> <input type="email" name="sender" id="id_for_sender" /></li><li><label for="id_for_cc_myself">Cc myself -></label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
.
, !
, ?
和:
)时才添加。label_suffix
。而且将优先于Form.label_suffix
。在运行时刻,后缀可以使用label_tag()
的label_suffix
参数覆盖。字段的顺序
as_p()
、as_ul()
和as_table()
中,字段以表单类中定义的顺序显示。例如,在ContactForm
示例中,字段定义的顺序为subject
, message
, sender
, cc_myself
。若要重新排序HTML 中的输出,只需改变字段在类中列出的顺序。错误如何显示
表单
对象,渲染时将自动运行表单的验证,HTML 输出将在出错字段的附近以<ul class="errorlist">
形式包含验证的错误。错误信息的位置与你使用的输出方法有关:>>> data = {'subject': '',... 'message': 'Hi there',... 'sender': 'invalid email address',... 'cc_myself': True}>>> f = ContactForm(data, auto_id=False)>>> print(f.as_table())<tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr><tr><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr><tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid email address.</li></ul><input type="email" name="sender" value="invalid email address" /></td></tr><tr><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr>>>> print(f.as_ul())<li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li><li>Message: <input type="text" name="message" value="Hi there" /></li><li><ul class="errorlist"><li>Enter a valid email address.</li></ul>Sender: <input type="email" name="sender" value="invalid email address" /></li><li>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li>>>> print(f.as_p())<p><ul class="errorlist"><li>This field is required.</li></ul></p><p>Subject: <input type="text" name="subject" maxlength="100" /></p><p>Message: <input type="text" name="message" value="Hi there" /></p><p><ul class="errorlist"><li>Enter a valid email address.</li></ul></p><p>Sender: <input type="email" name="sender" value="invalid email address" /></p><p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
自定义错误清单的格式
django.forms.utils.ErrorList
来格式化验证时的错误。如果你希望使用另外一种类来显示错误,可以在构造时传递(在Python 2 中将 __str__
替换为__unicode__
):>>> from django.forms.utils import ErrorList>>> class DivErrorList(ErrorList):... def __str__(self): # __unicode__ on Python 2... return self.as_divs()... def as_divs(self):... if not self: return ''... return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % e for e in self])>>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)>>> f.as_p()<div class="errorlist"><div class="error">This field is required.</div></div><p>Subject: <input type="text" name="subject" maxlength="100" /></p><p>Message: <input type="text" name="message" value="Hi there" /></p><div class="errorlist"><div class="error">Enter a valid email address.</div></div><p>Sender: <input type="email" name="sender" value="invalid email address" /></p><p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
django.forms.util
重命名为django.forms.utils
。更细粒度的输出
as_p()
、as_ul()
和as_table()
方法是为懒惰的程序员准备的简单快捷方法 —— 它们不是显示表单的唯一方式。BoundField
表单
实例的一个属性。__str__()
(Python 2 上为__unicode__
)方法显示该字段的HTML。BoundField
:>>> form = ContactForm()>>> print(form['subject'])<input id="id_subject" type="text" name="subject" maxlength="100" />
BoundField
:>>> form = ContactForm()>>> for boundfield in form: print(boundfield)<input id="id_subject" type="text" name="subject" maxlength="100" /><input type="text" name="message" id="id_message" /><input type="email" name="sender" id="id_sender" /><input type="checkbox" name="cc_myself" id="id_cc_myself" />
auto_id
设置有关:>>> f = ContactForm(auto_id=False)>>> print(f['message'])<input type="text" name="message" />>>> f = ContactForm(auto_id='id_%s')>>> print(f['message'])<input type="text" name="message" id="id_message" />
errors
属性。BoundField.
`errors`<ul class="errorlist">
形式显示:>>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}>>> f = ContactForm(data, auto_id=False)>>> print(f['message'])<input type="text" name="message" />>>> f['message'].errors['This field is required.']>>> print(f['message'].errors)<ul class="errorlist"><li>This field is required.</li></ul>>>> f['subject'].errors[]>>> print(f['subject'].errors)>>> str(f['subject'].errors)''
BoundField.
`label_tag`(_contents=None_, _attrs=None_, _label_suffix=None_)label_tag
方法单独渲染表单字段的label 标签:>>> f = ContactForm(data)>>> print(f['message'].label_tag())<label for="id_message">Message:</label>
contents
参数,它将替换自动生成的label 标签。另外一个可选的attrs
?参数可以包含<label>
标签额外的属性。label_suffix
(默认为一个冒号),或者当前字段的label_suffix
。可选的label_suffix
参数允许你覆盖之前设置的后缀。例如,你可以使用一个空字符串来隐藏已选择字段的label。如果在模板中需要这样做,你可以编写一个自定义的过滤器来允许传递参数给label_tag
。required_css_class
。BoundField.
`css_classes`()css_classes
方法访问这些CSS 类型:>>> f = ContactForm(data)>>> f['message'].css_classes()'required'
>>> f = ContactForm(data)>>> f['message'].css_classes('foo bar')'foo bar required'
BoundField.
`value`()Widget
渲染的值相同:>>> initial = {'subject': 'welcome'}>>> unbound_form = ContactForm(initial=initial)>>> bound_form = ContactForm(data, initial=initial)>>> print(unbound_form['subject'].value())welcome>>> print(bound_form['subject'].value())hi
BoundField.
`id_for_label`<label>
(尽管 label_tag()
将为你这么做):<label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }}