在HTML中,表单是在 <form>...</form>
中的一些元素,它允许访客做一些类似输入文本、选择选项、操作对象或空间等动作,然后发送这些信息到服务端
和它的元素 <input>
一样,表单必须指定两样东西:
何地:负责响应用户输入数据的URL地址
如何:数据请求使用的HTTP方法。
例如,Django admin的登录表单包含了一些 <input>
元素:用户名用 type=“text” ,密码用 type=“password” ,登录按钮用 type=“submit” 。它还包含一些用户看不到的隐藏文本字段,Django用它们来决定下一步行为。
Django会处理涉及表单的三个不同部分:
- 准备并重组数据,以便下一步的渲染
- 为数据创建HTML 表单
- 接收并处理客户端提交的表单及数据
您 可以 手动编写代码来实现,但Django 可以帮你完成所有这些工作。
Django的 Form 类
Django表单系统的核心组件是 Form 类。它与Django模型描述对象的逻辑结构、行为以及它呈现给我们内容的形式的方式大致相同, Form 类描述一张表单并决定它如何工作及呈现。
实例化、处理和渲染表单
在Django中渲染一个对象的时候,我们通常:
- 在视图中获取它(例如从数据库中取出)
- 将它传递给模板上下文
- 使用模板变量将它扩展为HTML标记
当我们实例化表单时,我们可以选择让它为空或者对它预先填充,例如使用:
- 来自已保存的模型实例的数据(例如在管理编辑表单的情况下)
- 我们从其他来源获取的数据
- 从前面一个HTML 表单提交过来的数据
字段详解
考虑一下比我们上面的小示例更有用的一张表单,我们可以用它在个人网站上实现“联系我”的功能:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
我们之前的表单只用了一个 CharField 类型的字段 your_name 。在这个例子中,我们的表单有四个字段: subject 、 message 、 sender 和 cc_myself 。只用到三种可用的字段类型: CharField 、 EmailField 和 BooleanField ;完整的字段类型清单请参看 Form fields 。
控件
每个表单字段都有一个相对应的 控件类 ,这个控件类又有对应的HTML表单控件,比如 <input type="text">
。
多数情况下,字段都有合适的默认控件。比如,默认情况下, CharField 有个 TextInput 控件,它会在HTML中生成一个<input type="text">
。
字段数据
无论用表单提交了什么数据,一旦通过调用 is_valid() 验证成功( is_valid() 返回 True ),已验证的表单数据将被放到 form.cleaned_data 字典中。这里的数据已经很好的为你转化为Python类型。
注解
此时您依然能够直接从 request.POST 中访问到未验证的数据,但最好还是使用经验证的数据。
使用表单模板
您只需将表单实例放到模板的上下文中即可。因此,如果您的表单在上下文中叫 form ,那么 {{ form }} 将渲染它相应的<label>
和<input>
元素
表单渲染选项
额外表单模板标签
不要忘记,一张表单的输出 不 包含外层 标签以及 submit 控件。这些必须由你自己提供。
对于 <label> / <input>
对,还有其他输出选项:
{{ form.as_table }} will render them as table cells wrapped in <tr> tags
{{ form.as_p }} will render them wrapped in <p> tags
{{ form.as_ul }} will render them wrapped in <li> tags
注意,您必须自己提供外层的 <table>
或 <ul>
元素。
下面是我们 ContactForm 实例用 {{ form.as_p }} 的输出:
<p><label for="id_subject">Subject:</label>
<input id="id_subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="id_message">Message:</label>
<textarea name="message" id="id_message" required></textarea></p>
<p><label for="id_sender">Sender:</label>
<input type="email" name="sender" id="id_sender" required></p>
<p><label for="id_cc_myself">Cc myself:</label>
<input type="checkbox" name="cc_myself" id="id_cc_myself"></p>
手动渲染字段
我们没有必要非要让Django来解包表单字段;如果我们喜欢,可以手动来处理(比如,让我们对字段重新排序)。每个字段都可以用 {{ form.name_of_field }} 作为表单的一个属性,并被相应的渲染在Django模板中。例如:
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="{{ form.sender.id_for_label }}">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
{{ form.cc_myself }}
</div>
完整的
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
</div>