第七章 表单
第七章-表单
这一章我们会讨论一下话题:
• 表单的工作流程
• 不可靠的输入
• 表单处理类视图
• 表单与 CRUD 视图
我们把 Django 表单放到一边,来讨论下常规情况下的表单是个什么样子。表单不仅长,而且有着多个需要填充的无趣的页面。可以说表单无所不在。我们每天都用到它。表单支撑了谷歌搜索框到脸书的点赞按钮这所有的一切。
Django 把使用表单时产生的验证和描述这类的大量繁重工作给抽象了。它也实现了多种的安全问题的最佳实践。可是,表单在处理自身多个状态之一时也是令人困惑的起因。
表单的工作原理
表单理解起来比较困难,因为它同不止一个请求-响应循环交互。最简单的场景是,你需要展示一个空表单,然后用户来正确地填充和提交表单。另外一种情况是它们输入一些无效的数据,表单需要重复的提交知道整个表单有效为止。
因此,表单表现出多种状态:
- 空表单: 在 Django 中此表单称为未绑定表单
- 已填充表单: Django 中该表单称为已绑定表单
- 有错误的已提交表单: 该表单称做已绑定表单,但不是有效表单
- 没有错误的已提交表单: 该表单称做已绑定且有效的表单
注意用户永远不会见到表单的最后状态。他们不必如此。提交的有效表单应当把用户带到表单提交成功之后的页面。
Django 中的表单
通过总结它们到一个层次,Django 的 form
类每个字段的状态,以及表单自身。表单拥有两个重要的状态属性,一如下面所示:
- is_bound: 如果返回值为假,则它是一个未绑定的表单,即,新的空表单,或者默认的字段值。如果返回值为真,表单被绑定,即,至少有一个用户设置的字段。
- is_valid(): 如果返回值为真,已绑定表单中的所有字段都拥有有效的数据。如果返回假,至少有一个字段中存在一部分无效数据,或者表单未被绑定。
举例来说,想象一下你需要一个接受用户名字和年龄的简单表单。这个类可以这样来定义:
# forms.py
from django import forms
class PersonDetailsForm(forms.Form):
name = forms.CharField(max_length=100)
age = forms.IntegerField()
该类可以以绑定或者不绑定方式来初始化,一如下面代码所示:
>>> f = PersonDetailsForm()
>>> print(f.as_p())
<p><label for="id_name">Name:</label> <input id="id_name" maxlength="100"
name="name" type="text" /></p>
<p><label for="id_age">Age:</label> <input id="id_age" name="age"
type="number" /></p>
>>> f.is_bound
False
>>> g = PersonDetailsForm({"name": "Blitz", "age": "30"})
>>> print(g.as_p())
<p><label for="id_name">Name:</label> <input id="id_name" maxlength="100"
name="name" type="text" value="Blitz" /></p>
<p><label for="id_age">Age:</label> <input id="id_age" name="age"
type="number" value="30" /></p>
>>> g.is_bound
True
要注意 HTML 是如何表现改变以包括它们中已绑定数据的值属性。
表单可以只在你创建表单对象时才被绑定,即,在构造器中。用户如何在类字典对象的最后面输入每个表单字段的值?
要想解决这个问题,你需要理解用户是如何与表单交互的。在下面的的图表中,用户打开用户账户表单,首先是正确地填充,并提交它,然后用有效信息重新提交表单:
如前面的表单所示,当用户提交表单时,在 request.POST
(它是一个 QueryDict
的实例)内部所有可调用的视图获取到全部的表单数据。表单使用类字典对象——以这种方式引用是因为它的行为类似于字典,来初始,并拥有一点额外的功能。
表单可以通过两种不同的方式来定义以发送数据表单: GET
或者 POST
。表单使用 METHOD=“GET”
定义以发送以 URL 编码的表单数据,例如,当你提交谷歌搜索时,URL 取得表单输入,即,搜索字符串显式地嵌入,比如 ?q=Cat+Pictures
就是如此。 GET
方法用来幂等表单,它不会对世界状态做出任何的最新改变。(不要太过于迂腐,多次处理有同样的效果就像一次处理)。大多数情况下,这意味着它只在重新取回数据时被用到。
不过,不计其数的表单都是使用 METHOD=“POST”
来定义的。这样,表单数据会一直发送 HTTP 请求的主体部分,而且它们对于用户来说是不可见的。它们被用于任何涉及到边际效应的事情,比如存储或者更新数据。
视你所定义表单类型的不同,当用户提交表单时,视图会重新取回 request.GET
或者 request.POST
中的表单数据。如同早前咱么提到的那样,它们中的哪一个都类似于字典。因此,你可以传递它到表单类构造器以获取绑定的 form
对象。
注释
The Breach Steve was curled up and snoring heavily in his large three-seater couch. For the last few weeks, he had been spending more than 12 hours at the office, and tonight was no exception. His phone lying on the carpet beeped.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论