Django4 中文入门教程 Django4.0 使用表单-使用表单模板

2024-02-25 开发教程 Django4 中文入门教程 匿名 4

您只需将表单实例放到模板的上下文中即可。因此,如果您的表单在上下文中叫 ​form ​,那么 ​{{ form }}​ 将渲染它相应的 ​<label>​和​<input>​元素。

表单渲染选项

对于 ​<label>​ / ​<input>​ 对,还有其他输出选项:

  • {{ form.as_table }}​ 会将它们呈现为包裹在 ​<tr>​ 标签中的表格单元格
  • {{ form.as_p }}​ 会将它们呈现在 ​<p>​ 标签中
  • {{ form.as_ul }}​ 会将它们呈现在 ​<li>​ 标签中

注意,您必须自己提供外层的 ​<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>

请注意,每个表单字段都有一个 ​id_<field-name>​ 这样的ID属性,它被附带的​label​标签引用。这对于确保表单可供屏幕阅读软件这样的辅助技术访问非常重要

手动渲染字段

我们没有必要非要让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>

完整的 ​<label>​ 元素还可以使用 ​label_tag()​ 来生成。例如:

<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
</div>

渲染表单错误信息

这种灵活性的代价需要多做一点工作。到目前为止,我们不必担心如何显示表单的错误信息,因为它们已经帮我们处理好了。下面的例子中,我们需要自己处理每个字段的错误信息以及表单整体的所有错误信息。注意表单顶部的 ​{{ form.non_field_errors }}​ 以及模板中对每个字段查找错误信息。

使用 ​{{ form.name_of_field.errors }}​ 显示该字段的错误信息列表,它被渲染成无序列表。看起来如下:

<ul class="errorlist">
<li>Sender is required.</li>
</ul>

该列表有一个CSS class ​errorlist ​,允许您自定义其样式。如果你想进一步自定义错误信息的显示,您可以通过遍历它们来实现:

{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}

非字段验证错误信息(或者通过使用像 ​form.as_p()​ 这样的辅助方法渲染产生在表单顶部的隐藏错误信息)渲染后会额外带上一个class ​nonfield ​以便与字段验证错误信息区分。例如, ​{{ form.non_field_errors }}​ 渲染后会像这样:

<ul class="errorlist nonfield">
<li>Generic validation error</li>
</ul>

遍历表单字段

如果您要给每个表单字段使用相同的HTML,您可以用 ​{% for %}​ 依次循环遍历每个字段来减少重复代码:

{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}

{{ field }} 的有用属性包括:

{{ field.label }}

字段的​label​,比如 ​Email ​​address​。

{{ field.label_tag }}

该字段的​label​封装在相应的HTML ​<label>​ 标签中。它包含表单的 ​label_suffix ​。例如,默认的 ​label_suffix ​是一个冒号:

<label for="id_email">Email address:</label>

{{ field.id_for_label }}
用于该字段的 ID(像上面的例子中的 id_email )。如果您要手动构建label,您可能要用这个来替换 label_tag 。例如,如果你有一些内嵌的JavaScript并且想要避免硬编码字段的ID,这也很有用。
{{ field.value }}
字段的值。例如 someone@example.com
{{ field.html_name }}
字段名称:用于其输入元素的name属性中。如果设置了表单前缀,它也会被加进去。
{{ field.help_text }}
与该字段关联的帮助文本
{{ field.errors }}
输出一个 ​<ul >​ ,其中包含这个字段的所有验证错误信息。你可以使用 ​{% for error in field.errors %}​ 循环来自定义错误信息的显示。在这种情况下,循环中的每个对象是包含错误信息的字符串。

{{ field.is_hidden }}
如果是隐藏字段,这个属性为 True ,否则为 False 。它作为模板变量没多大作用,但可用于条件测试,例如:

{% if field.is_hidden %}
{# Do something special #}
{% endif %}

{{ field.field }}
表单类中的 ​Field ​实例由 ​BoundField ​封装。您可以用它来访问 ​Field ​的属性,比如​{{ char_field.field.max_length }}​ 。

遍历隐藏字段和可见字段

如果您在手动布置模板中的表单,而不是依靠Django的默认表单布局,您可能希望将 ​<input type="hidden">​ 字段与非隐藏字段区别开来。例如,因为隐藏字段不显示任何内容,将错误消息放到该字段旁边可能会导致用户混淆——所以这些字段的错误应该以不同的方式处理。
Django在表单上提供了两种方法,允许您独立地遍历隐藏和可见的字段: ​hidden_fields()​ 和 ​visible_fields()​ 。以下是使用这两种方法对之前示例的修改:

{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}

这个示例没有处理隐藏字段中的任何错误信息。通常,隐藏字段中的错误象征着表单被篡改,因为正常的表单交互不会去改变它们。但是,您也可以轻松地为这些表单错误插入一些错误信息显示出来。

可复用的表单模板

如果你的网站在多个地方使用相同的表单渲染逻辑,你可以通过将表单的循环保存在一个独立的模板中,并覆盖表单的 ​template_name ​属性来使用自定义模板渲染表单,从而减少重复。下面的例子将导致 ​{{ form }}​ 被渲染成 ​form_snippet.html​ 模板的输出。
在你的模板中:

# In your template:
{{ form }}
# In form_snippet.html:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}

在你的表单中:

class MyForm(forms.Form):
template_name = 'form_snippet.html'
...