{"title":"使用表单","version":"5.1","locale":"zh-hans","docname":"topics/forms/index","url":"/zh-hans/5.1/topics/forms/","canonical":"https://djangodocs.dev/zh-hans/5.1/topics/forms/","summary":"关于本页文档 本页文档介绍了Web表单的基本内容以及它们在Django中是如何处理的。想更详细的了解表单的API，参见 表单 API ， 表单字段 ，以及 表单和字段验证 。 除非您计划搭建的网站和应用只发布内容且不接收访问者的输入，否则您就需要理解和使用表单。…","html":"<h1>使用表单<a class=\"heading-anchor\" href=\"#working-with-forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<aside class=\"admonition-about-this-document admonition\">\n<p class=\"admonition-title\">关于本页文档</p>\n<p>本页文档介绍了Web表单的基本内容以及它们在Django中是如何处理的。想更详细的了解表单的API，参见 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/\"><span class=\"doc\">表单 API</span></a> ， <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/\"><span class=\"doc\">表单字段</span></a> ，以及 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/validation/\"><span class=\"doc\">表单和字段验证</span></a> 。</p>\n</aside>\n<p>除非您计划搭建的网站和应用只发布内容且不接收访问者的输入，否则您就需要理解和使用表单。</p>\n<p>Django提供了一系列的工具和库来帮助您构建表单来接收网站访客的输入，然后处理以及响应这些输入。</p>\n<section id=\"html-forms\">\n<h2>HTML表单<a class=\"heading-anchor\" href=\"#html-forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>在HTML中，表单是在 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;...&lt;/form&gt;</span></code> 中的一些元素，它允许访客做一些类似输入文本、选择选项、操作对象或空间等动作，然后发送这些信息到服务端。</p>\n<p>一些表单界面元素（文本框或复选框）内置在HTML中。其他会更复杂些；像弹出日期选择或者允许您移动滑块或者操作控件，一般通过使用JavaScript，CSS以及HTML表单中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 元素来实现这些效果。</p>\n<p>和它的元素 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 一样，表单必须指定两样东西：</p>\n<ul class=\"simple\">\n<li><p><em>何地</em>：负责响应用户输入数据的URL地址</p></li>\n<li><p><em>如何</em>：数据请求使用的HTTP方法。</p></li>\n</ul>\n<p>例如，Django admin的登录表单包含了一些 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 元素：用户名用 <code class=\"docutils literal notranslate\"><span class=\"pre\">type=&quot;text&quot;</span></code> ，密码用 <code class=\"docutils literal notranslate\"><span class=\"pre\">type=&quot;password&quot;</span></code> ，登录按钮用 <code class=\"docutils literal notranslate\"><span class=\"pre\">type=&quot;submit&quot;</span></code> 。它还包含一些用户看不到的隐藏文本字段，Django用它们来决定下一步行为。</p>\n<p>它还告诉浏览器表单数据应该发往 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">action</span></code> 属性指定的URL—— <code class=\"docutils literal notranslate\"><span class=\"pre\">/admin/</span></code> ，并且应该使用它的 <code class=\"docutils literal notranslate\"><span class=\"pre\">method</span></code> 属性指定的HTTP方法—— <code class=\"docutils literal notranslate\"><span class=\"pre\">post</span></code> 。</p>\n<p>当 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input</span> <span class=\"pre\">type=&quot;submit&quot;</span> <span class=\"pre\">value=&quot;Log</span> <span class=\"pre\">in&quot;&gt;</span></code> 元素被触发的时候，数据会发送到 <code class=\"docutils literal notranslate\"><span class=\"pre\">/admin/</span></code> 。</p>\n<section id=\"get-and-post\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code><a class=\"heading-anchor\" href=\"#get-and-post\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>处理表单时只会用到 <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 两种HTTP方法。</p>\n<p>Django的登录表单使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 方法传输数据，在这个方法中浏览器会封装表单数据，为了传输会进行编码，然后发送到服务端并接收它的响应。</p>\n<p>相比之下，<code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 方法将提交的数据捆绑到一个字符串中，并用它来组成一个URL。该URL包含了数据要发送的地址以及一些键值对应的数据。如果您在Django文档中进行一次搜索，就会看到这点，它会生成一个形似 <code class=\"docutils literal notranslate\"><span class=\"pre\">https://docs.djangoproject.com/search/?q=forms&amp;release=1</span></code> 的URL。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 通常用于不同的目的。</p>\n<p>任何可能用于更改系统状态的请求应该使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> —— 比如一个更改数据库的请求。<code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 应该只被用于不会影响系统状态的请求。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 也不适合密码表格，因为密码会出现在 URL 中，因此也会出现在浏览器历史和服务器日志中，都是纯文本。它也不适合于大量的数据，或二进制数据，如图像。一个使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 请求管理表单的网络应用程序是一个安全风险：攻击者很容易模仿表单的请求来获得对系统敏感部分的访问。<code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code>，加上其他保护措施，如 Django 的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/csrf/\"><span class=\"doc\">CSRF 保护</span></a>，可以对访问进行更多控制。</p>\n<p>另一方面， <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 方法适用于诸如网页搜索表单这样的内容，因为这类呈现为一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 请求的URL很容易被存为书签、分享或重新提交。</p>\n</section>\n</section>\n<section id=\"django-s-role-in-forms\">\n<h2>Django在表单中的角色<a class=\"heading-anchor\" href=\"#django-s-role-in-forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>处理表单是一件挺复杂的事情。想想看Django的admin，许多不同类型的数据可能需要在一张表单中准备显示，渲染成HTML，使用方便的界面进行编辑，传到服务器，验证和清理数据，然后保存或跳过进行下一步处理。</p>\n<p>Django的表单功能可以简化和自动化上述工作的大部分内容，并且也能比大多数程序员自己编写代码去实现来的更安全些。</p>\n<p>Django会处理涉及表单的三个不同部分：</p>\n<ul class=\"simple\">\n<li><p>准备并重组数据，以便下一步的渲染</p></li>\n<li><p>为数据创建HTML 表单</p></li>\n<li><p>接收并处理客户端提交的表单及数据</p></li>\n</ul>\n<p>您 <em>可以</em> 手动编写代码来实现，但Django 可以帮你完成所有这些工作。</p>\n</section>\n<section id=\"forms-in-django\">\n<h2>Django 中的表单<a class=\"heading-anchor\" href=\"#forms-in-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>我们已经简单的描述过了HTML 表单，但是一个HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> 只是其所需的一部分。</p>\n<p>在网络应用的上下文中，“表单”可能指的是那个HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code>，或者指产生它的 Django <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a>，或者指它提交时返回的结构化数据，或者指这些部分的端到端工作集合。</p>\n<section id=\"the-django-form-class\">\n<h3>Django的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 类<a class=\"heading-anchor\" href=\"#the-django-form-class\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django表单系统的核心组件是 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 类。它与Django模型描述对象的逻辑结构、行为以及它呈现给我们内容的形式的方式大致相同， <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 类描述一张表单并决定它如何工作及呈现。</p>\n<p>类似于模型类的字段映射到数据库字段的方式，表单类的字段会映射到HTML表单的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 元素。 <a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/#django.forms.ModelForm\" title=\"django.forms.ModelForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code></a> 通过 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 映射模型类的字段到HTML表单的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 元素，Django admin就基于此。</p>\n<p>表单字段本身也是类；他们管理表单数据并在提交表单时执行验证。 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.DateField\" title=\"django.forms.DateField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DateField</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.FileField\" title=\"django.forms.FileField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FileField</span></code></a> 处理的数据类型差别很大，所以必须用来处理不同的字段。</p>\n<p>在浏览器中，表单字段以HTML“控件”（用户界面的一个片段）的形式展现给我们。每个字段类型都有与之相匹配的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/widgets/\"><span class=\"doc\">控件类</span></a> ，但必要时可以覆盖。</p>\n</section>\n<section id=\"instantiating-processing-and-rendering-forms\">\n<h3>实例化、处理和渲染表单<a class=\"heading-anchor\" href=\"#instantiating-processing-and-rendering-forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>在Django中渲染一个对象的时候，我们通常：</p>\n<ol class=\"arabic simple\">\n<li><p>在视图中获取它（例如从数据库中取出）</p></li>\n<li><p>将它传递给模板上下文</p></li>\n<li><p>使用模板变量将它扩展为HTML标记</p></li>\n</ol>\n<p>在模板中渲染表单几乎与渲染任何其他类型的对象的一样，但是存在一些关键性的差异。</p>\n<p>如果模型实例不包含数据，在模板中对它做任何处理几乎没什么用。但完全有理由用来渲染一张空表单——当我们希望用户来填充的时候就会这么做。</p>\n<p>所以当我们在视图中处理模型实例时，我们一般从数据库中获取它。当我们处理表单时，我们一般在视图中实例化它。</p>\n<p>当我们实例化一个表单时，我们可以选择将其保留为空，或者预先填充它，例如：</p>\n<ul class=\"simple\">\n<li><p>来自已保存的模型实例的数据（例如在管理编辑表单的情况下）</p></li>\n<li><p>我们从其他来源获取的数据</p></li>\n<li><p>从前面一个HTML 表单提交过来的数据</p></li>\n</ul>\n<p>最后一种情况最有趣，因为这使得用户不仅可以阅读网站，而且还可以将信息发回给它。</p>\n</section>\n</section>\n<section id=\"building-a-form\">\n<h2>构建一张表单<a class=\"heading-anchor\" href=\"#building-a-form\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"the-work-that-needs-to-be-done\">\n<h3>需要完成的工作<a class=\"heading-anchor\" href=\"#the-work-that-needs-to-be-done\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>假设您希望在您的网站上创建一张简易的表单，用来获取用户的名字。您需要在模板中使用类似代码：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">&quot;/your-name/&quot;</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">&quot;post&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;your_name&quot;</span><span class=\"p\">&gt;</span>Your name: <span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;your_name&quot;</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">&quot;text&quot;</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">&quot;your_name&quot;</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">current_name</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">&quot;submit&quot;</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">&quot;OK&quot;</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>这告诉浏览器将表单数据返回给URL <code class=\"docutils literal notranslate\"><span class=\"pre\">/your-name/</span></code> ，并使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 方法。它将显示一个标签为 &quot;Your name:&quot; 的文本字段，以及一个 &quot;OK&quot; 按钮。如果模板上下文包含一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">current_name</span></code> 变量，它会被预填充到 <code class=\"docutils literal notranslate\"><span class=\"pre\">your_name</span></code> 字段。</p>\n<p>您需要一个视图来渲染这个包含HTML表单的模板，并能适当提供 <code class=\"docutils literal notranslate\"><span class=\"pre\">current_name</span></code> 字段。</p>\n<p>提交表单时，发送给服务器的 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 请求将包含表单数据。</p>\n<p>现在，您还需要一个与该 <code class=\"docutils literal notranslate\"><span class=\"pre\">/your-name/</span></code> URL相对应的视图，该视图将在请求中找到相应的键/值对，然后对其进行处理。</p>\n<p>这是一个非常简单的表单。在实际应用中，一个表单可能包含几十个或数百个字段，其中许多字段可能需要预先填充，而且我们可能期望用户在完成操作之前多次执行编辑-提交周期。</p>\n<p>我们可能需要在浏览器中进行一些验证，甚至在表单提交之前；我们可能希望使用更复杂的字段 ，以允许用户做类似日期选择等操作。</p>\n<p>此刻，我们很容易通过使用Django来完成以上大部分工作。</p>\n</section>\n<section id=\"building-a-form-in-django\">\n<h3>在Django 中构建一张表单<a class=\"heading-anchor\" href=\"#building-a-form-in-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"the-form-class\">\n<h4><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 类<a class=\"heading-anchor\" href=\"#the-form-class\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>我们已经很清楚想要的HTML表单看起来会是什么样子。首先，在Django中这样做：</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">forms.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">forms</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">NameForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n    <span class=\"n\">your_name</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">label</span><span class=\"o\">=</span><span class=\"s2\">&quot;Your name&quot;</span><span class=\"p\">,</span> <span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>它定义了一个只包含一个字段（ <code class=\"docutils literal notranslate\"><span class=\"pre\">your_name</span></code> ）的  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 类。我们已经为这个字段提供了友好的标签，当它渲染后会显示在 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;label&gt;</span></code> 中（在这种情况下，如果我们省略之前指定的  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.Field.label\" title=\"django.forms.Field.label\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">label</span></code></a> ，它还是会自动生成一个一样的标签）。</p>\n<p>字段的最大长度由 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.CharField.max_length\" title=\"django.forms.CharField.max_length\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">max_length</span></code></a> 来定义。它做了两件事情。首先它在HTML的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 上增加了 <code class=\"docutils literal notranslate\"><span class=\"pre\">maxlength=&quot;100&quot;</span></code> （这样浏览器会在第一时间阻止用户输入超过这个数量的字符串）。其次它还会在Django收到浏览器传过来的表单时，对数据长度进行验证（也就是服务器端验证）。</p>\n<p>A <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> instance has an <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.is_valid\" title=\"django.forms.Form.is_valid\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">is_valid()</span></code></a> method, which runs\nvalidation routines for all its fields. When this method is called, if all\nfields contain valid data, it will:</p>\n<ul class=\"simple\">\n<li><p>返回 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code></p></li>\n<li><p>将表单的数据放到它的属性 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.cleaned_data\" title=\"django.forms.Form.cleaned_data\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">cleaned_data</span></code></a> 中。</p></li>\n</ul>\n<p>这样整个表单在第一次渲染时，会显示如下：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;your_name&quot;</span><span class=\"p\">&gt;</span>Your name: <span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;your_name&quot;</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">&quot;text&quot;</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">&quot;your_name&quot;</span> <span class=\"na\">maxlength</span><span class=\"o\">=</span><span class=\"s\">&quot;100&quot;</span> <span class=\"na\">required</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>注意它 <strong>没有</strong> 包含 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> 标签和提交按钮。我们必须自己在模板中提供。</p>\n</section>\n<section id=\"the-view\">\n<span id=\"using-a-form-in-a-view\"></span><h4>视图<a class=\"heading-anchor\" href=\"#the-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>发回Django网站的表单数据由视图来处理，一般和发布这个表单用的是同一个视图。这允许我们重用一些相同的逻辑。</p>\n<p>为了处理表单，我们需要将它实例化到我们希望发布的URL的对应的视图中：</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponseRedirect</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">NameForm</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_name</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># if this is a POST request we need to process the form data</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">method</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;POST&quot;</span><span class=\"p\">:</span>\n        <span class=\"c1\"># create a form instance and populate it with data from the request:</span>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">NameForm</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">)</span>\n        <span class=\"c1\"># check whether it&#39;s valid:</span>\n        <span class=\"k\">if</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># process the data in form.cleaned_data as required</span>\n            <span class=\"c1\"># ...</span>\n            <span class=\"c1\"># redirect to a new URL:</span>\n            <span class=\"k\">return</span> <span class=\"n\">HttpResponseRedirect</span><span class=\"p\">(</span><span class=\"s2\">&quot;/thanks/&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># if a GET (or any other method) we&#39;ll create a blank form</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">NameForm</span><span class=\"p\">()</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;name.html&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;form&quot;</span><span class=\"p\">:</span> <span class=\"n\">form</span><span class=\"p\">})</span>\n</code></pre></figure>\n<p>如果我们访问这个视图用的是 <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> 请求，它会创建一个空的表单实例并将其放置在模板上下文中进行渲染。这是我们在首次访问这个URL时能预料到会发生的情况。</p>\n<p>如果表单提交用的是 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 请求，那么该视图将再次创建一个表单实例并使用请求中的数据填充它： <code class=\"docutils literal notranslate\"><span class=\"pre\">form</span> <span class=\"pre\">=</span> <span class=\"pre\">NameForm(request.POST)</span></code> 这叫“绑定数据到表单” （现在它是一张 <em>绑定的</em> 表单）。</p>\n<p>我们调用表单的 <code class=\"docutils literal notranslate\"><span class=\"pre\">is_valid()</span></code> 方法；如果不为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ，我们带着表单返回到模板。这次表单不再为空（ <em>未绑定</em> ），所以HTML表单将用之前提交的数据进行填充，放到可以根据需要进行编辑和修正的位置。</p>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">is_valid()</span></code> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ，我们就能在其 <code class=\"docutils literal notranslate\"><span class=\"pre\">cleaned_data</span></code> 属性中找到所有通过验证的表单数据。我们可以在发送一个HTTP重定向告诉浏览器下一步去向之前用这些数据更新数据库或者做其他处理。</p>\n</section>\n<section id=\"the-template\">\n<span id=\"topics-forms-index-basic-form-template\"></span><h4>模板<a class=\"heading-anchor\" href=\"#the-template\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>我们没有必要在模板 <code class=\"docutils literal notranslate\"><span class=\"pre\">name.html</span></code> 中做过多的操作：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">&quot;/your-name/&quot;</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">&quot;post&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">csrf_token</span> <span class=\"cp\">%}</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">&quot;submit&quot;</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">&quot;Submit&quot;</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>所有的表单字段及其属性都将通过Django模板语言从 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form</span> <span class=\"pre\">}}</span></code> 中被解包成HTML标记。</p>\n<aside class=\"admonition-forms-and-cross-site-request-forgery-protection admonition\">\n<p class=\"admonition-title\">表格和跨站请求伪造保护</p>\n<p>Django自带一个简单易用的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/csrf/\"><span class=\"doc\">跨站请求伪造防护</span></a> 。当通过 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 方法提交一张启用了CSRF防护的表单时，您必须使用上例中这样的模板标签 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> 。但是，由于CSRF防护在模板中没有与表单直接绑定，因此这个标签在本页文档之后的示例中都将被忽略。</p>\n</aside>\n<aside class=\"admonition-html5-input-types-and-browser-validation admonition\">\n<p class=\"admonition-title\">HTML5输入类型和浏览器验证</p>\n<p>如果您的表单包含 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.URLField\" title=\"django.forms.URLField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">URLField</span></code></a> ， <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.EmailField\" title=\"django.forms.EmailField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">EmailField</span></code></a> 或者其他整数字段类型，Django 将使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">url</span></code> ， <code class=\"docutils literal notranslate\"><span class=\"pre\">email</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">number</span></code> HTML5 输入类型。默认情况下，浏览器可能会在这些字段上应用他们自己的验证，这也许比 Django 的验证更加严格。如果您想禁用这个行为，请在 <code class=\"docutils literal notranslate\"><span class=\"pre\">form</span></code> 标签上设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">novalidate</span></code> 属性，或者在字段上指定一个不同的控件，比如 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/widgets/#django.forms.TextInput\" title=\"django.forms.TextInput\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TextInput</span></code></a> 。</p>\n</aside>\n<p>现在我们有了一个可以工作的web表单，它通过一张Django <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 描述，由一个视图来处理并渲染成一个HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> 。</p>\n<p>以上是您入门需要了解的所有内容，但是表单框架提供了更多垂手可得的内容。一旦您理解了上述过程的基础知识，您应该再了解下表单系统的其他功能，然后学习更多的底层机制。</p>\n</section>\n</section>\n</section>\n<section id=\"more-about-django-form-classes\">\n<h2>详解Django <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> 类<a class=\"heading-anchor\" href=\"#more-about-django-form-classes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>所有表单类都作为 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.forms.Form</span></code></a> 或者 <a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/#django.forms.ModelForm\" title=\"django.forms.ModelForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.forms.ModelForm</span></code></a> 的子类来创建。您可以把 <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code> 想象成 <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> 的子类。实际上 <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code> 从（私有） <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> 类继承了通用功能，但是这个实现细节不怎么重要。</p>\n<aside class=\"admonition-models-and-forms admonition\">\n<p class=\"admonition-title\">模型和表单</p>\n<p>实际上，如果您的表单是要直接用来添加或编辑Django模型，用 <a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/\"><span class=\"doc\">ModelForm</span></a> ，可以省时、省力、省代码，因为它会根据 <code class=\"docutils literal notranslate\"><span class=\"pre\">Model</span></code> 类构建一张对应字段及其属性的表单。</p>\n</aside>\n<section id=\"bound-and-unbound-form-instances\">\n<h3>绑定的和未绑定的表单实例<a class=\"heading-anchor\" href=\"#bound-and-unbound-form-instances\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The distinction between <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#ref-forms-api-bound-unbound\"><span class=\"std std-ref\">绑定和非绑定表单</span></a> is important:</p>\n<ul class=\"simple\">\n<li><p>未绑定的表单没有与其关联的数据。当渲染给用户的时候，它会是空的或者包含默认值。</p></li>\n<li><p>绑定的表单拥有已提交的数据，因此可以用来判断数据是否合法。如果渲染了一张非法的绑定的表单，它将包含内联的错误信息，告知用户要纠正哪些数据。</p></li>\n</ul>\n<p>表单的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.is_bound\" title=\"django.forms.Form.is_bound\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_bound</span></code></a> 属性将告诉您一张表单是否具有绑定的数据。</p>\n</section>\n<section id=\"more-on-fields\">\n<h3>字段详解<a class=\"heading-anchor\" href=\"#more-on-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>考虑一下比我们上面的小示例更有用的一张表单，我们可以用它在个人网站上实现“联系我”的功能：</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">forms.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">forms</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ContactForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n    <span class=\"n\">subject</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">message</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">widget</span><span class=\"o\">=</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Textarea</span><span class=\"p\">)</span>\n    <span class=\"n\">sender</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">()</span>\n    <span class=\"n\">cc_myself</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">BooleanField</span><span class=\"p\">(</span><span class=\"n\">required</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>我们之前的表单只用了一个 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.CharField\" title=\"django.forms.CharField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CharField</span></code></a> 类型的字段 <code class=\"docutils literal notranslate\"><span class=\"pre\">your_name</span></code> 。在这个例子中，我们的表单有四个字段： <code class=\"docutils literal notranslate\"><span class=\"pre\">subject</span></code> 、 <code class=\"docutils literal notranslate\"><span class=\"pre\">message</span></code> 、 <code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">cc_myself</span></code> 。只用到三种可用的字段类型：  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.CharField\" title=\"django.forms.CharField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CharField</span></code></a> 、 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.EmailField\" title=\"django.forms.EmailField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">EmailField</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.BooleanField\" title=\"django.forms.BooleanField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BooleanField</span></code></a> ；完整的字段类型清单请参看  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/\"><span class=\"doc\">表单字段</span></a> 。</p>\n<section id=\"widgets\">\n<h4>控件<a class=\"heading-anchor\" href=\"#widgets\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>每个表单字段都有一个相对应的  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/widgets/\"><span class=\"doc\">控件类</span></a> ，这个控件类又有对应的HTML表单控件，比如 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input</span> <span class=\"pre\">type=&quot;text&quot;&gt;</span></code> 。</p>\n<p>多数情况下，字段都有合适的默认控件。比如，默认情况下， <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.CharField\" title=\"django.forms.CharField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CharField</span></code></a> 有个  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/widgets/#django.forms.TextInput\" title=\"django.forms.TextInput\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TextInput</span></code></a> 控件，它会在HTML中生成一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input</span> <span class=\"pre\">type=&quot;text&quot;&gt;</span></code> 。如果您想要的是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;textarea&gt;</span> <span class=\"pre\">``</span> <span class=\"pre\">，您要在定义表单字段的时候指定控件，就像我们对</span> <span class=\"pre\">``message</span></code> 字段那样处理。</p>\n</section>\n<section id=\"field-data\">\n<h4>字段数据<a class=\"heading-anchor\" href=\"#field-data\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>无论用表单提交了什么数据，一旦通过调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">is_valid()</span></code> 验证成功（  <code class=\"docutils literal notranslate\"><span class=\"pre\">is_valid()</span></code> 返回 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ），已验证的表单数据将被放到 <code class=\"docutils literal notranslate\"><span class=\"pre\">form.cleaned_data</span></code> 字典中。这里的数据已经很好的为你转化为Python类型。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>此时您依然能够直接从 <code class=\"docutils literal notranslate\"><span class=\"pre\">request.POST</span></code> 中访问到未验证的数据，但最好还是使用经验证的数据。</p>\n</aside>\n<p>在上面的联系表单示例中， <code class=\"docutils literal notranslate\"><span class=\"pre\">cc_myself</span></code> 会被转化成一个布尔值。同样的，字段 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.IntegerField\" title=\"django.forms.IntegerField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">IntegerField</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.FloatField\" title=\"django.forms.FloatField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FloatField</span></code></a> 的值分别会被转化为Python的 <code class=\"docutils literal notranslate\"><span class=\"pre\">int</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">float</span></code> 类型。</p>\n<p>下面例举了如何在视图中处理表单数据：</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.mail</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">send_mail</span>\n\n<span class=\"k\">if</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n    <span class=\"n\">subject</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">[</span><span class=\"s2\">&quot;subject&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">message</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">[</span><span class=\"s2\">&quot;message&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">sender</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">[</span><span class=\"s2\">&quot;sender&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">cc_myself</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">[</span><span class=\"s2\">&quot;cc_myself&quot;</span><span class=\"p\">]</span>\n\n    <span class=\"n\">recipients</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;info@example.com&quot;</span><span class=\"p\">]</span>\n    <span class=\"k\">if</span> <span class=\"n\">cc_myself</span><span class=\"p\">:</span>\n        <span class=\"n\">recipients</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">)</span>\n\n    <span class=\"n\">send_mail</span><span class=\"p\">(</span><span class=\"n\">subject</span><span class=\"p\">,</span> <span class=\"n\">message</span><span class=\"p\">,</span> <span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"n\">recipients</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponseRedirect</span><span class=\"p\">(</span><span class=\"s2\">&quot;/thanks/&quot;</span><span class=\"p\">)</span>\n</code></pre></figure>\n<aside class=\"admonition admonition-tip\">\n<p class=\"admonition-title\">Tip</p>\n<p>更多关于从Django中发送电子邮件的内容，请参见  <a class=\"reference internal\" href=\"/zh-hans/5.1/topics/email/\"><span class=\"doc\">发送邮件</span></a> 。</p>\n</aside>\n<p>有些字段类型需要一些额外的处理。例如，使用表单上传文件就要以不同的方式处理（它们可以从 <code class=\"docutils literal notranslate\"><span class=\"pre\">request.FILES</span></code> 获取，而不是 <code class=\"docutils literal notranslate\"><span class=\"pre\">request.POST</span></code> 中）。有关如何使用表单处理文件上传的详细信息，请参见 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#binding-uploaded-files\"><span class=\"std std-ref\">将上传的文件绑定到表单中</span></a> 。</p>\n</section>\n</section>\n</section>\n<section id=\"working-with-form-templates\">\n<h2>使用表单模板<a class=\"heading-anchor\" href=\"#working-with-form-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>您只需将表单实例放到模板的上下文中即可。因此，如果您的表单在上下文中叫 <code class=\"docutils literal notranslate\"><span class=\"pre\">form</span></code> ，那么  <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form</span> <span class=\"pre\">}}</span></code> 将渲染它相应的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;label&gt;</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input&gt;</span></code> 元素。</p>\n<aside class=\"admonition-additional-form-template-furniture admonition\">\n<p class=\"admonition-title\">额外表单模板标签</p>\n<p>不要忘记，一张表单的输出 <em>不</em> 包含外层 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> 标签以及 <code class=\"docutils literal notranslate\"><span class=\"pre\">submit</span></code> 控件。这些必须由你自己提供。</p>\n</aside>\n<section id=\"reusable-form-templates\">\n<span id=\"id1\"></span><h3>可复用的表单模板<a class=\"heading-anchor\" href=\"#reusable-form-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>在渲染表单时生成的 HTML 输出本身是通过模板生成的。你可以通过创建一个合适的模板文件，并设置自定义的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/settings/#std-setting-FORM_RENDERER\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">FORM_RENDERER</span></code></a> 来控制这个过程，以在整个站点范围内使用 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/renderers/#django.forms.renderers.BaseRenderer.form_template_name\" title=\"django.forms.renderers.BaseRenderer.form_template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">form_template_name</span></code></a>。你也可以通过覆盖表单的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.template_name\" title=\"django.forms.Form.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a> 属性来自定义每个表单，以使用自定义模板呈现表单，或者直接将模板名称传递给 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.render\" title=\"django.forms.Form.render\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Form.render()</span></code></a>。</p>\n<p>下面的示例将导致 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form</span> <span class=\"pre\">}}</span></code> 被呈现为 <code class=\"docutils literal notranslate\"><span class=\"pre\">form_snippet.html</span></code> 模板的输出：</p>\n<p>在你的模板中：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code># In your template:\n<span class=\"cp\">{{</span> <span class=\"nv\">form</span> <span class=\"cp\">}}</span>\n\n# In form_snippet.html:\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">field</span> <span class=\"k\">in</span> <span class=\"nv\">form</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">field.errors</span> <span class=\"cp\">}}</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">field.label_tag</span> <span class=\"cp\">}}</span> <span class=\"cp\">{{</span> <span class=\"nv\">field</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>然后你可以配置 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/settings/#std-setting-FORM_RENDERER\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">FORM_RENDERER</span></code></a> 设置：</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">settings.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms.renderers</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TemplatesSetting</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomFormRenderer</span><span class=\"p\">(</span><span class=\"n\">TemplatesSetting</span><span class=\"p\">):</span>\n    <span class=\"n\">form_template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;form_snippet.html&quot;</span>\n\n\n<span class=\"n\">FORM_RENDERER</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;project.settings.CustomFormRenderer&quot;</span>\n</code></pre></figure>\n<p>...或者对于单个表单：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;form_snippet.html&quot;</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>...或者对于单个表单实例的单次渲染，通过将模板名称传递给 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.render\" title=\"django.forms.Form.render\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Form.render()</span></code></a>。以下是在视图中使用此方法的示例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">MyForm</span><span class=\"p\">()</span>\n    <span class=\"n\">rendered_form</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"s2\">&quot;form_snippet.html&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;form&quot;</span><span class=\"p\">:</span> <span class=\"n\">rendered_form</span><span class=\"p\">}</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;index.html&quot;</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>请参阅 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#ref-forms-api-outputting-html\"><span class=\"std std-ref\">将表单输出为 HTML</span></a> 以获取更多详细信息。</p>\n</section>\n<section id=\"reusable-field-group-templates\">\n<span id=\"id2\"></span><h3>可重用的字段组模板<a class=\"heading-anchor\" href=\"#reusable-field-group-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"5.0\">\n<p class=\"version-note-title\">New in Django 5.0</p></aside>\n<p>每个字段都可以在模板中使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form.name_of_field</span> <span class=\"pre\">}}</span></code> 作为表单的属性。一个字段具有 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.BoundField.as_field_group\" title=\"django.forms.BoundField.as_field_group\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_field_group()</span></code></a> 方法，该方法将字段的相关元素渲染为一个组，包括标签、小部件、错误和帮助文本。</p>\n<p>这允许编写通用模板，以满足所需的字段元素布局。例如：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">form.non_field_errors</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.subject.as_field_group</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.message.as_field_group</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.sender.as_field_group</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.cc_myself.as_field_group</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>默认情况下，Django 使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/field.html&quot;</span></code> 模板，该模板设计用于与默认的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/div.html&quot;</span></code> 表单样式一起使用。</p>\n<p>默认模板可以通过在项目级别的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/settings/#std-setting-FORM_RENDERER\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">FORM_RENDERER</span></code></a> 中设置 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/renderers/#django.forms.renderers.BaseRenderer.field_template_name\" title=\"django.forms.renderers.BaseRenderer.field_template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">field_template_name</span></code></a> 来自定义：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms.renderers</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TemplatesSetting</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomFormRenderer</span><span class=\"p\">(</span><span class=\"n\">TemplatesSetting</span><span class=\"p\">):</span>\n    <span class=\"n\">field_template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;field_snippet.html&quot;</span>\n</code></pre></div>\n<p>… 或在单个字段上：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n    <span class=\"n\">subject</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">template_name</span><span class=\"o\">=</span><span class=\"s2\">&quot;my_custom_template.html&quot;</span><span class=\"p\">)</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>… 或在每个请求的基础上通过调用 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.BoundField.render\" title=\"django.forms.BoundField.render\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">BoundField.render()</span></code></a> 并提供模板名称：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">ContactForm</span><span class=\"p\">()</span>\n    <span class=\"n\">subject</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"p\">[</span><span class=\"s2\">&quot;subject&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;subject&quot;</span><span class=\"p\">:</span> <span class=\"n\">subject</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"s2\">&quot;my_custom_template.html&quot;</span><span class=\"p\">)}</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;index.html&quot;</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"rendering-fields-manually\">\n<h3>手动渲染字段<a class=\"heading-anchor\" href=\"#rendering-fields-manually\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>还可以对字段的渲染进行更细粒度的控制。通常情况下，这将在一个自定义字段模板中实现，以便可以编写一次并在每个字段中重用模板。但也可以直接从表单上的字段属性中访问。例如：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">form.non_field_errors</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.subject.errors</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.subject.id_for_label</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>Email subject:<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.subject</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.message.errors</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.message.id_for_label</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>Your message:<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.message</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.sender.errors</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.sender.id_for_label</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>Your email address:<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.sender</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.cc_myself.errors</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.cc_myself.id_for_label</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>CC yourself?<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.cc_myself</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>完整的 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;label&gt;</span></code> 元素还可以使用 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.BoundField.label_tag\" title=\"django.forms.BoundField.label_tag\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">label_tag()</span></code></a> 来生成。例如：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.subject.errors</span> <span class=\"cp\">}}</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.subject.label_tag</span> <span class=\"cp\">}}</span>\n    <span class=\"cp\">{{</span> <span class=\"nv\">form.subject</span> <span class=\"cp\">}}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<section id=\"rendering-form-error-messages\">\n<h4>渲染表单错误信息<a class=\"heading-anchor\" href=\"#rendering-form-error-messages\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>这种灵活性的代价需要多做一点工作。到目前为止，我们不必担心如何显示表单的错误信息，因为它们已经帮我们处理好了。下面的例子中，我们需要自己处理每个字段的错误信息以及表单整体的所有错误信息。注意表单顶部的 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form.non_field_errors</span> <span class=\"pre\">}}</span></code> 以及模板中对每个字段查找错误信息。</p>\n<p>使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form.name_of_field.errors</span> <span class=\"pre\">}}</span></code> 显示该字段的错误信息列表，它被渲染成无序列表。看起来如下：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;errorlist&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Sender is required.<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>该列表有一个CSS class <code class=\"docutils literal notranslate\"><span class=\"pre\">errorlist</span></code> ，允许您自定义其样式。如果你想进一步自定义错误信息的显示，您可以通过遍历它们来实现：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">form.subject.errors</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ol</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">error</span> <span class=\"k\">in</span> <span class=\"nv\">form.subject.errors</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">strong</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">error</span><span class=\"o\">|</span><span class=\"nf\">escape</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">strong</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ol</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>非字段验证错误信息（或者通过使用像 <code class=\"docutils literal notranslate\"><span class=\"pre\">form.as_p()</span></code> 这样的辅助方法渲染产生在表单顶部的隐藏错误信息）渲染后会额外带上一个class  <code class=\"docutils literal notranslate\"><span class=\"pre\">nonfield</span></code> 以便与字段验证错误信息区分。例如， <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form.non_field_errors</span> <span class=\"pre\">}}</span></code> 渲染后会像这样：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;errorlist nonfield&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Generic validation error<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>更多错误、样式以及在模板中使用表单属性的内容，请参阅 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/\"><span class=\"doc\">表单 API</span></a> 。</p>\n</section>\n</section>\n<section id=\"looping-over-the-form-s-fields\">\n<h3>遍历表单字段<a class=\"heading-anchor\" href=\"#looping-over-the-form-s-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>如果您要给每个表单字段使用相同的HTML，您可以用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for</span> <span class=\"pre\">%}</span></code> 依次循环遍历每个字段来减少重复代码：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">field</span> <span class=\"k\">in</span> <span class=\"nv\">form</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">field.errors</span> <span class=\"cp\">}}</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">field.label_tag</span> <span class=\"cp\">}}</span> <span class=\"cp\">{{</span> <span class=\"nv\">field</span> <span class=\"cp\">}}</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">field.help_text</span> <span class=\"cp\">%}</span>\n          <span class=\"p\">&lt;</span><span class=\"nt\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;help&quot;</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">field.auto_id</span> <span class=\"cp\">}}</span><span class=\"s\">_helptext&quot;</span><span class=\"p\">&gt;</span>\n            <span class=\"cp\">{{</span> <span class=\"nv\">field.help_text</span><span class=\"o\">|</span><span class=\"nf\">safe</span> <span class=\"cp\">}}</span>\n          <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Useful attributes on <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field</span> <span class=\"pre\">}}</span></code> include:</p>\n<dl class=\"simple\">\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.errors</span> <span class=\"pre\">}}</span></code></dt><dd><p>输出一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;ul</span> <span class=\"pre\">class=&quot;errorlist&quot;&gt;</span></code> ，其中包含这个字段的所有验证错误信息。你可以使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for</span> <span class=\"pre\">error</span> <span class=\"pre\">in</span> <span class=\"pre\">field.errors</span> <span class=\"pre\">%}</span></code> 循环来自定义错误信息的显示。在这种情况下，循环中的每个对象是包含错误信息的字符串。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.field</span> <span class=\"pre\">}}</span></code></dt><dd><p>表单类中的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.Field\" title=\"django.forms.Field\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Field</span></code></a> 实例由 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.BoundField\" title=\"django.forms.BoundField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BoundField</span></code></a> 封装。您可以用它来访问 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/fields/#django.forms.Field\" title=\"django.forms.Field\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Field</span></code></a> 的属性，比如 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">char_field.field.max_length</span> <span class=\"pre\">}}</span></code> 。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.help_text</span> <span class=\"pre\">}}</span></code></dt><dd><p>与该字段关联的帮助文本。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.html_name</span> <span class=\"pre\">}}</span></code></dt><dd><p>字段名称：用于其输入元素的name属性中。如果设置了表单前缀，它也会被加进去。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.id_for_label</span> <span class=\"pre\">}}</span></code></dt><dd><p>用于该字段的 ID（像上面的例子中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">id_email</span></code> ）。如果您要手动构建label，您可能要用这个来替换 <code class=\"docutils literal notranslate\"><span class=\"pre\">label_tag</span></code> 。例如，如果你有一些内嵌的JavaScript并且想要避免硬编码字段的ID，这也很有用。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.is_hidden</span> <span class=\"pre\">}}</span></code></dt><dd><p>如果是隐藏字段，这个属性为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ，否则为 <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> 。它作为模板变量没多大作用，但可用于条件测试，例如：</p>\n</dd>\n</dl>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">field.is_hidden</span> <span class=\"cp\">%}</span>\n   <span class=\"c\">{# Do something special #}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<dl>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.label</span> <span class=\"pre\">}}</span></code></dt><dd><p>字段的label，比如 <code class=\"docutils literal notranslate\"><span class=\"pre\">Email</span> <span class=\"pre\">address</span></code>。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.label_tag</span> <span class=\"pre\">}}</span></code></dt><dd><p>字段的标签将包装在适当的 HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;label&gt;</span></code> 标签中。这包括表单的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.Form.label_suffix\" title=\"django.forms.Form.label_suffix\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">label_suffix</span></code></a>。例如，默认的 <code class=\"docutils literal notranslate\"><span class=\"pre\">label_suffix</span></code> 是冒号：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">&quot;id_email&quot;</span><span class=\"p\">&gt;</span>Email address:<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.legend_tag</span> <span class=\"pre\">}}</span></code></dt><dd><p>类似于 <code class=\"docutils literal notranslate\"><span class=\"pre\">field.label_tag</span></code>，但在多个输入被包装在 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;fieldset&gt;</span></code> 中的小部件上使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;legend&gt;</span></code> 标签代替 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;label&gt;</span></code>。</p>\n</dd>\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.use_fieldset</span> <span class=\"pre\">}}</span></code></dt><dd><p>如果表单字段的小部件包含应该在 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;fieldset&gt;</span></code> 中语义上分组的多个输入，并且带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;legend&gt;</span></code> 以提高可访问性，则此属性为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>。在模板中的示例用法：</p>\n</dd>\n</dl>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">field.use_fieldset</span> <span class=\"cp\">%}</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">field.label</span> <span class=\"cp\">%}{{</span> <span class=\"nv\">field.legend_tag</span> <span class=\"cp\">}}{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">else</span> <span class=\"cp\">%}</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">field.label</span> <span class=\"cp\">%}{{</span> <span class=\"nv\">field.label_tag</span> <span class=\"cp\">}}{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{{</span> <span class=\"nv\">field</span> <span class=\"cp\">}}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">field.use_fieldset</span> <span class=\"cp\">%}</span><span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span><span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<dl class=\"simple\">\n<dt><code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">field.value</span> <span class=\"pre\">}}</span></code></dt><dd><p>字段的值。例如 <code class=\"docutils literal notranslate\"><span class=\"pre\">someone&#64;example.com</span></code> 。</p>\n</dd>\n</dl>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p>有关字段属性及方法的完整清单，请参阅 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/api/#django.forms.BoundField\" title=\"django.forms.BoundField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BoundField</span></code></a> 。</p>\n</aside>\n<section id=\"looping-over-hidden-and-visible-fields\">\n<h4>遍历隐藏字段和可见字段<a class=\"heading-anchor\" href=\"#looping-over-hidden-and-visible-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>如果您在手动布置模板中的表单，而不是依靠Django的默认表单布局，您可能希望将 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;input</span> <span class=\"pre\">type=&quot;hidden&quot;&gt;</span></code> 字段与非隐藏字段区别开来。例如，因为隐藏字段不显示任何内容，将错误消息“放到”该字段旁边可能会导致用户混淆——所以这些字段的错误应该以不同的方式处理。</p>\n<p>Django在表单上提供了两种方法，允许您独立地遍历隐藏和可见的字段： <code class=\"docutils literal notranslate\"><span class=\"pre\">hidden_fields()</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">visible_fields()</span></code> 。以下是使用这两种方法对之前示例的修改：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"c\">{# Include the hidden fields #}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">hidden</span> <span class=\"k\">in</span> <span class=\"nv\">form.hidden_fields</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{{</span> <span class=\"nv\">hidden</span> <span class=\"cp\">}}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n<span class=\"c\">{# Include the visible fields #}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">field</span> <span class=\"k\">in</span> <span class=\"nv\">form.visible_fields</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;fieldWrapper&quot;</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">field.errors</span> <span class=\"cp\">}}</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">field.label_tag</span> <span class=\"cp\">}}</span> <span class=\"cp\">{{</span> <span class=\"nv\">field</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>这个示例没有处理隐藏字段中的任何错误信息。通常，隐藏字段中的错误象征着表单被篡改，因为正常的表单交互不会去改变它们。但是，您也可以轻松地为这些表单错误插入一些错误信息显示出来。</p>\n</section>\n</section>\n</section>\n<section id=\"further-topics\">\n<h2>更多相关主题<a class=\"heading-anchor\" href=\"#further-topics\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>以上只涵盖了表单的基础知识，但它还可以做更多的事情：</p>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/\">表单集</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#using-initial-data-with-a-formset\">使用formset的初始数据</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#limiting-the-maximum-number-of-forms\">限制表单的最大数量</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#limiting-the-maximum-number-of-instantiated-forms\">限制实例化表单的最大数量</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#formset-validation\">Formset验证</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#validating-the-number-of-forms-in-a-formset\">验证formset中表单的数量</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#dealing-with-ordering-and-deletion-of-forms\">处理表单的排序和删除</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#adding-additional-fields-to-a-formset\">给一个formset添加额外字段</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#passing-custom-parameters-to-formset-forms\">传递自定义参数到formset表单</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#customizing-a-formset-s-prefix\">自定义formset的前缀</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/formsets/#using-a-formset-in-views-and-templates\">在视图和模板中使用formset</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/\">从模型创建表单</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/#modelform\"><code class=\"docutils literal notranslate\"><span class=\"pre\">ModelForm</span></code></a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/#model-formsets\">模型表单集</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/modelforms/#inline-formsets\">内联表单集</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/media/\">表单资源（ <code class=\"docutils literal notranslate\"><span class=\"pre\">Media</span></code> 类）</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/media/#assets-as-a-static-definition\">资源作为静态定义</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/media/#media-as-a-dynamic-property\">把 <code class=\"docutils literal notranslate\"><span class=\"pre\">Media</span></code> 作为动态属性</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/media/#paths-in-asset-definitions\">资源定义中的路径</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/media/#media-objects\"><code class=\"docutils literal notranslate\"><span class=\"pre\">Media</span></code> 对象</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"/zh-hans/5.1/topics/forms/media/#media-on-forms\">表单上的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Media</span></code></a></li>\n</ul>\n</li>\n</ul>\n</div>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<dl class=\"simple\">\n<dt><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/forms/\"><span class=\"doc\">The Forms Reference</span></a></dt><dd><p>覆盖完整的API 参考，包括表单字段、表单控件以及表单和字段的验证。</p>\n</dd>\n</dl>\n</aside>\n</section>","rootId":"working-with-forms","toc":[{"title":"HTML表单","anchor":"html-forms","children":[{"title":"GET 和 POST","anchor":"get-and-post","children":[]}]},{"title":"Django在表单中的角色","anchor":"django-s-role-in-forms","children":[]},{"title":"Django 中的表单","anchor":"forms-in-django","children":[{"title":"Django的 Form 类","anchor":"the-django-form-class","children":[]},{"title":"实例化、处理和渲染表单","anchor":"instantiating-processing-and-rendering-forms","children":[]}]},{"title":"构建一张表单","anchor":"building-a-form","children":[{"title":"需要完成的工作","anchor":"the-work-that-needs-to-be-done","children":[]},{"title":"在Django 中构建一张表单","anchor":"building-a-form-in-django","children":[{"title":"Form 类","anchor":"the-form-class","children":[]},{"title":"视图","anchor":"the-view","children":[]},{"title":"模板","anchor":"the-template","children":[]}]}]},{"title":"详解Django Form 类","anchor":"more-about-django-form-classes","children":[{"title":"绑定的和未绑定的表单实例","anchor":"bound-and-unbound-form-instances","children":[]},{"title":"字段详解","anchor":"more-on-fields","children":[{"title":"控件","anchor":"widgets","children":[]},{"title":"字段数据","anchor":"field-data","children":[]}]}]},{"title":"使用表单模板","anchor":"working-with-form-templates","children":[{"title":"可复用的表单模板","anchor":"reusable-form-templates","children":[]},{"title":"可重用的字段组模板","anchor":"reusable-field-group-templates","children":[]},{"title":"手动渲染字段","anchor":"rendering-fields-manually","children":[{"title":"渲染表单错误信息","anchor":"rendering-form-error-messages","children":[]}]},{"title":"遍历表单字段","anchor":"looping-over-the-form-s-fields","children":[{"title":"遍历隐藏字段和可见字段","anchor":"looping-over-hidden-and-visible-fields","children":[]}]}]},{"title":"更多相关主题","anchor":"further-topics","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/5.1/topics/"}],"prev":{"docname":"topics/http/sessions","title":"如何使用会话","url":"/zh-hans/5.1/topics/http/sessions/"},"next":{"docname":"topics/forms/formsets","title":"表单集","url":"/zh-hans/5.1/topics/forms/formsets/"},"formats":{"html":"/zh-hans/5.1/topics/forms/","markdown":"/zh-hans/5.1/topics/forms.md","json":"/zh-hans/5.1/topics/forms.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/topics/forms/index.txt","official":"https://docs.djangoproject.com/zh-hans/5.1/topics/forms/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}