{"title":"表单集","version":"4.2","locale":"zh-hans","docname":"topics/forms/formsets","url":"/zh-hans/4.2/topics/forms/formsets/","canonical":"https://djangodocs.dev/zh-hans/4.2/topics/forms/formsets/","summary":"class BaseFormSet Link to this definition # 表单集是一种用于在同一页面上处理多个表单的抽象层。它最适合与数据网格进行比较。假设您有以下表单： Python console Copy >>> from django import forms >>> class ArticleForm…","html":"<h1>表单集<a class=\"heading-anchor\" href=\"#formsets\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">BaseFormSet</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>表单集是一种用于在同一页面上处理多个表单的抽象层。它最适合与数据网格进行比较。假设您有以下表单：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><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<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ArticleForm</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=\"gp\">... </span>    <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">()</span>\n<span class=\"gp\">... </span>    <span class=\"n\">pub_date</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n</code></pre></div>\n<p>您可能希望允许用户同时创建多篇文章。要从 <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleForm</span></code> 创建一个表单集，您可以这样做：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>现在，您已经创建了一个名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleFormSet</span></code> 的表单集类。实例化表单集使您能够迭代表单集中的表单，并像普通表单一样显示它们：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">as_table</span><span class=\"p\">())</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n</code></pre></div>\n<p>如您所见，它只显示了一个空表单。显示的空表单的数量由 <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> 参数控制。默认情况下，<a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a> 定义了一个额外的表单；下面的示例将创建一个表单集类，以显示两个空表单：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">extra</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>遍历 formset 将按照它们创建的顺序渲染表单。你可以通过为 <code class=\"docutils literal notranslate\"><span class=\"pre\">__iter__()</span></code> 方法提供替代的实现来改变这个顺序。</p>\n<p>表单集也可以被索引然后返回对应的表单。如果您已经覆盖了 <code class=\"docutils literal notranslate\"><span class=\"pre\">__iter__</span></code> ，则还需覆盖  <code class=\"docutils literal notranslate\"><span class=\"pre\">__getitem__</span></code> 让它具备匹配行为。</p>\n<section id=\"using-initial-data-with-a-formset\">\n<span id=\"formsets-initial-data\"></span><h2>使用formset的初始数据<a class=\"heading-anchor\" href=\"#using-initial-data-with-a-formset\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>初始数据是驱动表单集主要可用性的关键。如上所示，您可以定义额外表单的数量。这意味着您告诉表单集要显示多少个额外表单，除了它从初始数据生成的表单数量。让我们看一个示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">extra</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span>\n<span class=\"gp\">... </span>            <span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Django is now open source&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>            <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">today</span><span class=\"p\">(),</span>\n<span class=\"gp\">... </span>        <span class=\"p\">}</span>\n<span class=\"gp\">... </span>    <span class=\"p\">]</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">as_table</span><span class=\"p\">())</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; value=&quot;Django is now open source&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; value=&quot;2008-05-12&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-title&quot; id=&quot;id_form-1-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-pub_date&quot; id=&quot;id_form-1-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-title&quot; id=&quot;id_form-2-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-pub_date&quot; id=&quot;id_form-2-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n</code></pre></div>\n<p>现在上面显示了三张表单。一张是传了初始数据的，另外两张是额外的。需要注意的是，我们通过传递一个字典列表来作为初始数据。</p>\n<p>如果您使用了 <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span></code> 来显示formset，那么您需要在处理formset提交时传入相同的 <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span></code> ，以便formset检测用户更改了哪些表单。例如，您可能有这样的： <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleFormSet(request.POST,</span> <span class=\"pre\">initial=[...])</span></code> 。</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p><a class=\"reference internal\" href=\"/zh-hans/4.2/topics/forms/modelforms/#model-formsets\"><span class=\"std std-ref\">创建模型表单集</span></a>。</p>\n</aside>\n</section>\n<section id=\"limiting-the-maximum-number-of-forms\">\n<span id=\"formsets-max-num\"></span><h2>限制表单的最大数量<a class=\"heading-anchor\" href=\"#limiting-the-maximum-number-of-forms\"><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/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a> 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 参数允许您限制表单集将显示的表单数量：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">extra</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">max_num</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">as_table</span><span class=\"p\">())</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n</code></pre></div>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 的值大于初始数据现有数量，那空白表单可显示的数量取决于 <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> 的数量，只要总表单数不超过 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 。例如， <code class=\"docutils literal notranslate\"><span class=\"pre\">extra=2</span></code> ， <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num=2</span></code> 并且formset有一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span></code> 初始化项，则会显示一张初始化表单和一张空白表单。</p>\n<p>如果初始数据项的数量超过 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> ，那么 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 的值会被无视，所有初始数据表单都会显示，并且也不会有额外的表单显示。例如，假设 <code class=\"docutils literal notranslate\"><span class=\"pre\">extra=3</span></code> ， <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num=1</span></code> 并且formset有两个初始化项，那么只会显示两张有初始化数据的表单。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 的值 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> (默认值)，它限制最多显示(1000)张表单，其实这相当于没有限制。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 默认只影响显示多少数量的表单而不影响验证。如果将 <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max=True</span></code> 传给 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a>，那么 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 将会影响验证。参见 <a class=\"reference internal\" href=\"#validate-max\"><span class=\"std std-ref\">validate_max</span></a> 。</p>\n</section>\n<section id=\"limiting-the-maximum-number-of-instantiated-forms\">\n<span id=\"formsets-absolute-max\"></span><h2>限制实例化表单的最大数量<a class=\"heading-anchor\" href=\"#limiting-the-maximum-number-of-instantiated-forms\"><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/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a> 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> 参数允许限制在提供 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 数据时可以实例化的表单数量。这可以防止使用伪造的 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 请求进行内存耗尽攻击：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms.formsets</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">absolute_max</span><span class=\"o\">=</span><span class=\"mi\">1500</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1501&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">forms</span><span class=\"p\">)</span>\n<span class=\"go\">1500</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Please submit at most 1000 forms.&#39;]</span>\n</code></pre></div>\n<p>当 <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> 时，它默认为 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span> <span class=\"pre\">+</span> <span class=\"pre\">1000</span></code>。（如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>，则默认为 <code class=\"docutils literal notranslate\"><span class=\"pre\">2000</span></code>）。</p>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> 小于 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>，将引发 <code class=\"docutils literal notranslate\"><span class=\"pre\">ValueError</span></code>。</p>\n</section>\n<section id=\"formset-validation\">\n<h2>Formset验证<a class=\"heading-anchor\" href=\"#formset-validation\"><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\">is_valid</span></code> 方法，提供了一种方便的方式来验证表单集中的所有表单：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">True</span>\n</code></pre></div>\n<p>我们没有向表单集传递任何数据，这导致表单有效。表单集足够智能，可以忽略未更改的额外表单。如果我们提供一个无效的文章：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1904-06-16&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>  <span class=\"c1\"># &lt;-- this date is missing but required</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {&#39;pub_date&#39;: [&#39;This field is required.&#39;]}]</span>\n</code></pre></div>\n<p>正如我们看到的，<code class=\"docutils literal notranslate\"><span class=\"pre\">formset.errors</span></code> 是一张列表，它的内容对应着formset中表单。两张表都进行了验证，并且第二项中出现了预期的错误消息。</p>\n<p>和使用普通 <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> 一样，formset表单中的每个字段都可能包含HTML属性，例如用于浏览器验证的 <code class=\"docutils literal notranslate\"><span class=\"pre\">maxlength</span></code> 。但是由于表单添加、删除的时候会影响属性 <code class=\"docutils literal notranslate\"><span class=\"pre\">required</span></code> 的验证，表单集中的表单不会包含此属性。</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.total_error_count\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">total_error_count</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.total_error_count\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>要检查表单集中有多少个错误，可以使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">total_error_count</span></code> 方法：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Using the previous example</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {&#39;pub_date&#39;: [&#39;This field is required.&#39;]}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span><span class=\"p\">)</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">total_error_count</span><span class=\"p\">()</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p>我们还可以检查表单数据是否与初始数据不同（即，表单被发送而没有任何数据）：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">has_changed</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n</code></pre></div>\n<section id=\"understanding-the-managementform\">\n<span id=\"id1\"></span><h3>理解 <code class=\"docutils literal notranslate\"><span class=\"pre\">ManagementForm</span></code><a class=\"heading-anchor\" href=\"#understanding-the-managementform\"><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\">form-TOTAL_FORMS</span></code>、<code class=\"docutils literal notranslate\"><span class=\"pre\">form-INITIAL_FORMS</span></code>）。这些数据是 <code class=\"docutils literal notranslate\"><span class=\"pre\">ManagementForm</span></code> 所必需的。这个表单用于由表单集管理的表单集合。如果不提供这些管理数据，表单集将无效：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n</code></pre></div>\n<p>它被用来跟踪显示了多少个表单实例。如果您通过JavaScript添加新表单，那您同样需要增加相应内容到那些数量字段中，另一方面，如果您允许通过JavaScript来删除已存在对象，那么您需确认被移除的对象已经被标记在 <code class=\"docutils literal notranslate\"><span class=\"pre\">form-#-DELETE</span></code> 中并被放到 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 内。无论如何，所有表单都要确保在 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 数据中。</p>\n<p>管理表单以formset的一项属性而存在。在模板中渲染formset时，你可以使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">my_formset.management_form</span> <span class=\"pre\">}}</span></code>  (将my_formset替换为自己的formset名称)渲染出所有管理表单的数据。</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\">form-TOTAL_FORMS</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">form-INITIAL_FORMS</span></code> 字段，管理表单还包括 <code class=\"docutils literal notranslate\"><span class=\"pre\">form-MIN_NUM_FORMS</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">form-MAX_NUM_FORMS</span></code> 字段。它们与管理表单的其他部分一起输出，但只是为了方便客户端的代码。这些字段不是必须的，所以没有显示在示例的 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 数据中。</p>\n</aside>\n</section>\n<section id=\"total-form-count-and-initial-form-count\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">total_form_count</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">initial_form_count</span></code><a class=\"heading-anchor\" href=\"#total-form-count-and-initial-form-count\"><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\">BaseFormSet</span></code> 有一对与 <code class=\"docutils literal notranslate\"><span class=\"pre\">ManagementForm</span></code> 密切相关的方法， <code class=\"docutils literal notranslate\"><span class=\"pre\">total_form_count</span></code>  和  <code class=\"docutils literal notranslate\"><span class=\"pre\">initial_form_count</span></code> 。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">total_form_count</span></code> 返回该formset内表单的总和。 <code class=\"docutils literal notranslate\"><span class=\"pre\">initial_form_count</span></code> 返回该formset内预填充的表单数量，同时用于定义需要多少表单。你可能永远不会重写这两个方法，因此在使用之前请理解它们的用途。</p>\n</section>\n<section id=\"empty-form\">\n<span id=\"id2\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">empty_form</span></code><a class=\"heading-anchor\" href=\"#empty-form\"><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\">BaseFormSet``有一项属性``empty_form</span></code>，它返回一个以``__prefix__`` 为前缀的表单实例，这是为了方便在动态表单中配合JavaScript使用。</p>\n</section>\n<section id=\"error-messages\">\n<span id=\"formsets-error-messages\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">error_messages</span></code><a class=\"heading-anchor\" href=\"#error-messages\"><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\">error_messages</span></code> 参数允许您覆盖表单集将引发的默认消息。传递一个字典，其中的键与您想要覆盖的错误消息匹配。错误消息键包括 <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code>、<code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">'missing_management_form'</span></code>。<code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> 错误消息可能包含 <code class=\"docutils literal notranslate\"><span class=\"pre\">%(num)d</span></code>，它将分别替换为 <code class=\"docutils literal notranslate\"><span class=\"pre\">min_num</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>。</p>\n<p>例如，以下是当管理表单丢失时的默认错误消息：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">({})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;ManagementForm data is missing or has been tampered with. Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. You may need to file a bug report if the issue persists.&#39;]</span>\n</code></pre></div>\n<p>以下是一个自定义错误消息的示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"p\">{},</span> <span class=\"n\">error_messages</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;missing_management_form&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Sorry, something went wrong.&quot;</span><span class=\"p\">}</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Sorry, something went wrong.&#39;]</span>\n</code></pre></div>\n<aside class=\"version-note version-changed\" data-version=\"4.1\">\n<p class=\"version-note-title\">Changed in Django 4.1</p><p>添加了 <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> 键。</p>\n</aside>\n</section>\n<section id=\"custom-formset-validation\">\n<h3>自定义formset验证<a class=\"heading-anchor\" href=\"#custom-formset-validation\"><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\">Form</span></code> 类上的 <code class=\"docutils literal notranslate\"><span class=\"pre\">clean</span></code> 方法。这是您在表单集级别定义自己的验证规则的地方：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ValidationError</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">clean</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span><span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;Checks that no two articles have the same title.&quot;&quot;&quot;</span>\n<span class=\"gp\">... </span>        <span class=\"k\">if</span> <span class=\"nb\">any</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">errors</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>            <span class=\"c1\"># Don&#39;t bother validating the formset unless each form is valid on its own</span>\n<span class=\"gp\">... </span>            <span class=\"k\">return</span>\n<span class=\"gp\">... </span>        <span class=\"n\">titles</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n<span class=\"gp\">... </span>        <span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">forms</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">can_delete</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_should_delete_form</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>                <span class=\"k\">continue</span>\n<span class=\"gp\">... </span>            <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>            <span class=\"k\">if</span> <span class=\"n\">title</span> <span class=\"ow\">in</span> <span class=\"n\">titles</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>                <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Articles in a set must have distinct titles.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>            <span class=\"n\">titles</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1904-06-16&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1912-06-23&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Articles in a set must have distinct titles.&#39;]</span>\n</code></pre></div>\n<p>formset的 <code class=\"docutils literal notranslate\"><span class=\"pre\">clean</span></code> 方法会在所有 <code class=\"docutils literal notranslate\"><span class=\"pre\">Form.clean</span></code> 方法调用完之后被调用。可以使用formset的 <code class=\"docutils literal notranslate\"><span class=\"pre\">non_form_errors()</span></code> 方法来查看错误信息。</p>\n<p>非表单错误将用一个额外的类 <code class=\"docutils literal notranslate\"><span class=\"pre\">nonform</span></code> 来呈现，以帮助区分它们与表单特定错误。例如，<code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">formset.non_form_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 nonform&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Articles in a set must have distinct titles.<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</section>\n</section>\n<section id=\"validating-the-number-of-forms-in-a-formset\">\n<h2>验证formset中表单的数量<a class=\"heading-anchor\" href=\"#validating-the-number-of-forms-in-a-formset\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django提供了一对方法来验证已提交的表单的最小和最大数量。如果要对应用程序进行更多的可定制验证，那需要使用自定义formset验证。</p>\n<section id=\"validate-max\">\n<span id=\"id3\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max</span></code><a class=\"heading-anchor\" href=\"#validate-max\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>如果方法 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a> 有设置参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max=True</span></code> ，验证还会检查数据集内表单的数量，减去那些被标记为删除的表单数量，剩余数量需小于等于 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 。</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">max_num</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">validate_max</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-TOTAL_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;2&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-INITIAL_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-0-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Test&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-0-pub_date&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;1904-06-16&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-1-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Test 2&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-1-pub_date&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;1912-06-23&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Please submit at most 1 form.&#39;]</span>\n</code></pre></div>\n<p>即使因为提供的初始数据量过大而超过了 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 所定义的，<code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max=True</span></code> 还是会严格针对 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> 进行验证。</p>\n<p>错误消息可以通过将 <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> 消息传递给 <a class=\"reference internal\" href=\"#formsets-error-messages\"><span class=\"std std-ref\">error_messages</span></a> 参数来自定义。</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\">validate_max</span></code> 如何，如果数据集中的表单数量超过 <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code>，那么表单将无法验证，就像 <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max</span></code> 被设置一样，另外只有第一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> 的表单会被验证。其余的将被完全截断。这是为了防止使用伪造的 POST 请求的内存耗尽攻击。参见 <a class=\"reference internal\" href=\"#formsets-absolute-max\"><span class=\"std std-ref\">限制实例化表单的最大数量</span></a>。</p>\n</aside>\n</section>\n<section id=\"validate-min\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">validate_min</span></code><a class=\"heading-anchor\" href=\"#validate-min\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>如果方法 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a> 有传参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_min=True</span></code> ，还会验证数据集中的表单的数量减去那些被标记为删除的表单数量是否大于或等于 <code class=\"docutils literal notranslate\"><span class=\"pre\">min_num</span></code> 定义的数量。</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">min_num</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">validate_min</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-TOTAL_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;2&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-INITIAL_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-0-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Test&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-0-pub_date&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;1904-06-16&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-1-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Test 2&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-1-pub_date&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;1912-06-23&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Please submit at least 3 forms.&#39;]</span>\n</code></pre></div>\n<p>错误消息可以通过将 <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code> 消息传递给 <a class=\"reference internal\" href=\"#formsets-error-messages\"><span class=\"std std-ref\">error_messages</span></a> 参数来自定义。</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\">validate_min</span></code> 的值是什么，如果一个 formset 不包含任何数据，那么将显示 <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span> <span class=\"pre\">+</span> <span class=\"pre\">min_num</span></code> 空表单。</p>\n</aside>\n</section>\n</section>\n<section id=\"dealing-with-ordering-and-deletion-of-forms\">\n<h2>处理表单的排序和删除<a class=\"heading-anchor\" href=\"#dealing-with-ordering-and-deletion-of-forms\"><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/4.2/ref/forms/formsets/#django.forms.formsets.formset_factory\" title=\"django.forms.formsets.formset_factory\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">formset_factory()</span></code></a> 提供了两个可选参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> 来协助处理formset中表单的排序和删除。</p>\n<section id=\"can-order\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code><a class=\"heading-anchor\" href=\"#can-order\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.can_order\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">can_order</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.can_order\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>默认值： <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code></p>\n<p>让你创建一个具有排序功能的表单集：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">can_order</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">]</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">as_table</span><span class=\"p\">())</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; value=&quot;Article #1&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; value=&quot;2008-05-10&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-ORDER&quot;&gt;Order:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;number&quot; name=&quot;form-0-ORDER&quot; value=&quot;1&quot; id=&quot;id_form-0-ORDER&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-title&quot; value=&quot;Article #2&quot; id=&quot;id_form-1-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-pub_date&quot; value=&quot;2008-05-11&quot; id=&quot;id_form-1-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-ORDER&quot;&gt;Order:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;number&quot; name=&quot;form-1-ORDER&quot; value=&quot;2&quot; id=&quot;id_form-1-ORDER&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-title&quot; id=&quot;id_form-2-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-pub_date&quot; id=&quot;id_form-2-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-ORDER&quot;&gt;Order:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;number&quot; name=&quot;form-2-ORDER&quot; id=&quot;id_form-2-ORDER&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n</code></pre></div>\n<p>这将为每个表单添加一个额外的字段。这个新字段名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">ORDER</span></code>，是一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">forms.IntegerField</span></code>。对于来自初始数据的表单，它会自动分配给它们一个数字值。让我们看看当用户更改这些值时会发生什么：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;3&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-10&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-ORDER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-11&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-ORDER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #3&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-01&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-ORDER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">data</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">],</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">True</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">ordered_forms</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">{&#39;pub_date&#39;: datetime.date(2008, 5, 1), &#39;ORDER&#39;: 0, &#39;title&#39;: &#39;Article #3&#39;}</span>\n<span class=\"go\">{&#39;pub_date&#39;: datetime.date(2008, 5, 11), &#39;ORDER&#39;: 1, &#39;title&#39;: &#39;Article #2&#39;}</span>\n<span class=\"go\">{&#39;pub_date&#39;: datetime.date(2008, 5, 10), &#39;ORDER&#39;: 2, &#39;title&#39;: &#39;Article #1&#39;}</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet\" title=\"django.forms.formsets.BaseFormSet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseFormSet</span></code></a> 也提供了 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.ordering_widget\" title=\"django.forms.formsets.BaseFormSet.ordering_widget\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">ordering_widget</span></code></a> 属性和 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.get_ordering_widget\" title=\"django.forms.formsets.BaseFormSet.get_ordering_widget\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_ordering_widget()</span></code></a> 方法，来控制与 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.can_order\" title=\"django.forms.formsets.BaseFormSet.can_order\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">can_order</span></code></a> 一起使用的小部件。</p>\n<section id=\"ordering-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">ordering_widget</span></code><a class=\"heading-anchor\" href=\"#ordering-widget\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.ordering_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">ordering_widget</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.ordering_widget\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>默认: <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/widgets/#django.forms.NumberInput\" title=\"django.forms.NumberInput\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">NumberInput</span></code></a></p>\n<p>将 <code class=\"docutils literal notranslate\"><span class=\"pre\">ordering_widget</span></code> 设置为指定用于 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code> 的小部件类：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ordering_widget</span> <span class=\"o\">=</span> <span class=\"n\">HiddenInput</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_order</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"get-ordering-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">get_ordering_widget</span></code><a class=\"heading-anchor\" href=\"#get-ordering-widget\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.get_ordering_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_ordering_widget</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.get_ordering_widget\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果需要为 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code> 提供一个小部件实例，可以重写 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_ordering_widget()</span></code>：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_ordering_widget</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"n\">HiddenInput</span><span class=\"p\">(</span><span class=\"n\">attrs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ordering&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_order</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"can-delete\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code><a class=\"heading-anchor\" href=\"#can-delete\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.can_delete\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">can_delete</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.can_delete\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>默认值： <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code></p>\n<p>允许你创建一个具有选择要删除的表单的表单集：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">can_delete</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">]</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">as_table</span><span class=\"p\">())</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; value=&quot;Article #1&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; value=&quot;2008-05-10&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-DELETE&quot;&gt;Delete:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;form-0-DELETE&quot; id=&quot;id_form-0-DELETE&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-title&quot; value=&quot;Article #2&quot; id=&quot;id_form-1-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-pub_date&quot; value=&quot;2008-05-11&quot; id=&quot;id_form-1-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-1-DELETE&quot;&gt;Delete:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;form-1-DELETE&quot; id=&quot;id_form-1-DELETE&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-title&quot; id=&quot;id_form-2-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-pub_date&quot; id=&quot;id_form-2-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-2-DELETE&quot;&gt;Delete:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;form-2-DELETE&quot; id=&quot;id_form-2-DELETE&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n</code></pre></div>\n<p>类似于 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code>，这会为每个表单添加一个名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">DELETE</span></code> 的新字段，它是一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">forms.BooleanField</span></code>。当数据传递时，标记任何一个删除字段，你可以使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">deleted_forms</span></code> 来访问它们：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;3&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-10&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-DELETE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;on&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-11&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-DELETE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-DELETE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">data</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">],</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">[</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span> <span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">deleted_forms</span><span class=\"p\">]</span>\n<span class=\"go\">[{&#39;DELETE&#39;: True, &#39;pub_date&#39;: datetime.date(2008, 5, 10), &#39;title&#39;: &#39;Article #1&#39;}]</span>\n</code></pre></div>\n<p>如果你使用 <a class=\"reference internal\" href=\"/zh-hans/4.2/topics/forms/modelforms/#django.forms.models.BaseModelFormSet\" title=\"django.forms.models.BaseModelFormSet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelFormSet</span></code></a> ，那些标记为删除的表单模型实例会在调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.save()</span></code> 时被删除。</p>\n<p>如果你调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.save(commit=False)</span></code>，对象将不会被自动删除。你需要在每一个 <a class=\"reference internal\" href=\"/zh-hans/4.2/topics/forms/modelforms/#django.forms.models.BaseModelFormSet.deleted_objects\" title=\"django.forms.models.BaseModelFormSet.deleted_objects\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">formset.deleted_objects</span></code></a> 上调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code> 来实际删除它们：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">instances</span> <span class=\"o\">=</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">commit</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">obj</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">deleted_objects</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n</code></pre></div>\n<p>另一方面，如果您使用的是普通的 <code class=\"docutils literal notranslate\"><span class=\"pre\">FormSet</span></code> ，那需要您自己去处理 <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.deleted_forms</span></code> ，可能写在formset的 <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> 方法中，因为对于阐述删除一张表单还没有一个通用的概念。</p>\n<p><a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet\" title=\"django.forms.formsets.BaseFormSet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseFormSet</span></code></a> 也提供了一个 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.deletion_widget\" title=\"django.forms.formsets.BaseFormSet.deletion_widget\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">deletion_widget</span></code></a> 属性和 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.get_deletion_widget\" title=\"django.forms.formsets.BaseFormSet.get_deletion_widget\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_deletion_widget()</span></code></a> 方法，控制用于 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.can_delete\" title=\"django.forms.formsets.BaseFormSet.can_delete\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">can_delete</span></code></a> 的部件。</p>\n<section id=\"deletion-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">deletion_widget</span></code><a class=\"heading-anchor\" href=\"#deletion-widget\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.deletion_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">deletion_widget</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.deletion_widget\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>默认： <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/widgets/#django.forms.CheckboxInput\" title=\"django.forms.CheckboxInput\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CheckboxInput</span></code></a></p>\n<p>将 <code class=\"docutils literal notranslate\"><span class=\"pre\">deletion_widget</span></code> 设置为指定与 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> 一起使用的小部件类：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"n\">deletion_widget</span> <span class=\"o\">=</span> <span class=\"n\">HiddenInput</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_delete</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"get-deletion-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">get_deletion_widget</span></code><a class=\"heading-anchor\" href=\"#get-deletion-widget\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.get_deletion_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_deletion_widget</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.get_deletion_widget\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果需要为 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> 提供一个小部件实例，可以重写 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_deletion_widget()</span></code>：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_deletion_widget</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"n\">HiddenInput</span><span class=\"p\">(</span><span class=\"n\">attrs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;deletion&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_delete</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"can-delete-extra\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete_extra</span></code><a class=\"heading-anchor\" href=\"#can-delete-extra\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.can_delete_extra\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">can_delete_extra</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.can_delete_extra\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>默认： <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code></p>\n<p>在设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete=True</span></code> 的同时，指定 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete_extra=False</span></code> 将移除删除额外表格的选项。</p>\n</section>\n</section>\n<section id=\"adding-additional-fields-to-a-formset\">\n<h2>给一个formset添加额外字段<a class=\"heading-anchor\" href=\"#adding-additional-fields-to-a-formset\"><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\">add_fields</span></code> 方法。你可以重写这个方法来添加自己的字段，甚至重新定义订单和删除字段的默认字段/属性：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">add_fields</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">form</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">add_fields</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>        <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">fields</span><span class=\"p\">[</span><span class=\"s2\">&quot;my_field&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">as_table</span><span class=\"p\">())</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n<span class=\"go\">&lt;tr&gt;&lt;th&gt;&lt;label for=&quot;id_form-0-my_field&quot;&gt;My field:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-my_field&quot; id=&quot;id_form-0-my_field&quot;&gt;&lt;/td&gt;&lt;/tr&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"passing-custom-parameters-to-formset-forms\">\n<span id=\"custom-formset-form-kwargs\"></span><h2>传递自定义参数到formset表单<a class=\"heading-anchor\" href=\"#passing-custom-parameters-to-formset-forms\"><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\">MyArticleForm</span></code>。你可以在实例化表单集时传递这个参数：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyArticleForm</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"n\">user</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"n\">user</span>\n<span class=\"gp\">... </span>        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">MyArticleForm</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">form_kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;user&quot;</span><span class=\"p\">:</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"p\">})</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">form_kwargs</span></code> 也可能取决于特定的表单实例。表单集基类提供了一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_form_kwargs</span></code> 方法。这个方法接受一个参数 - 表单集中表单的索引。对于 <a class=\"reference internal\" href=\"#empty-form\"><span class=\"std std-ref\">empty_form</span></a>，索引为 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_form_kwargs</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"n\">kwargs</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_form_kwargs</span><span class=\"p\">(</span><span class=\"n\">index</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>        <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s2\">&quot;custom_kwarg&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">index</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"n\">kwargs</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">MyArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"customizing-a-formset-s-prefix\">\n<span id=\"formset-prefix\"></span><h2>自定义formset的前缀<a class=\"heading-anchor\" href=\"#customizing-a-formset-s-prefix\"><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\">'form'</span></code> ，但可以使用formset的 <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> 参数来自定义。</p>\n<p>例如，在默认情况下，您可能会看到:</p>\n<div class=\"code-block\" data-language=\"html\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Html</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=\"Html 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_form-0-title&quot;</span><span class=\"p\">&gt;</span>Title:<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\">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;form-0-title&quot;</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;id_form-0-title&quot;</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>但使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleFormset(prefix='article')</span></code> 的话就会变为：</p>\n<div class=\"code-block\" data-language=\"html\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Html</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=\"Html 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_article-0-title&quot;</span><span class=\"p\">&gt;</span>Title:<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\">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;article-0-title&quot;</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;id_article-0-title&quot;</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>如果您想 :ref:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>在视图中使用多个formset &lt;multiple-formsets-in-view&gt; ` ，这个参数会很有用。</p>\n</section>\n<section id=\"using-a-formset-in-views-and-templates\">\n<span id=\"formset-rendering\"></span><h2>在视图和模板中使用formset<a class=\"heading-anchor\" href=\"#using-a-formset-in-views-and-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>表单集具有以下与渲染相关的属性和方法：</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.renderer\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">renderer</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.renderer\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>指定 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/renderers/\"><span class=\"doc\">渲染器</span></a> 用于表单集。默认为 <code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">FORM_RENDER</span></code> 配置所指定的渲染器。</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>如果将表单集转换为字符串，例如通过 <code class=\"docutils literal notranslate\"><span class=\"pre\">print(formset)</span></code> 或在模板中使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">formset</span> <span class=\"pre\">}}</span></code>，则会呈现模板的名称。</p>\n<p>默认情况下，返回渲染器的 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/renderers/#django.forms.renderers.BaseRenderer.formset_template_name\" title=\"django.forms.renderers.BaseRenderer.formset_template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">formset_template_name</span></code></a> 值的属性。你可以将其设置为字符串模板名称，以便在特定的表单集类中覆盖它。</p>\n<p>这个模板将用于呈现表单集的管理表单，然后根据表单的 <a class=\"reference internal\" href=\"/zh-hans/4.2/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> 定义的模板来呈现表单集中的每个表单。</p>\n<aside class=\"version-note version-changed\" data-version=\"4.1\">\n<p class=\"version-note-title\">Changed in Django 4.1</p><p>在旧版本中，<code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code> 默认为字符串值 <code class=\"docutils literal notranslate\"><span class=\"pre\">'django/forms/formset/default.html'</span></code>。</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_div\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_div</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_div\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><aside class=\"version-note version-added\" data-version=\"4.1\">\n<p class=\"version-note-title\">New in Django 4.1</p></aside>\n<p>在调用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_div\" title=\"django.forms.formsets.BaseFormSet.as_div\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_div()</span></code></a> 时使用的模板名称。默认情况下，这是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/div.html&quot;</span></code>。这个模板呈现表单集的管理表单，然后根据表单的 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/api/#django.forms.Form.as_div\" title=\"django.forms.Form.as_div\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_div()</span></code></a> 方法来呈现表单集中的每个表单。</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_p\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_p</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_p\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>在调用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_p\" title=\"django.forms.formsets.BaseFormSet.as_p\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_p()</span></code></a> 时使用的模板名称。默认情况下，这是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/p.html&quot;</span></code>。这个模板呈现表单集的管理表单，然后根据表单的 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/api/#django.forms.Form.as_p\" title=\"django.forms.Form.as_p\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_p()</span></code></a> 方法来呈现表单集中的每个表单。</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_table\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_table</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_table\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>在调用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_table\" title=\"django.forms.formsets.BaseFormSet.as_table\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_table()</span></code></a> 时使用的模板名称。默认情况下，这是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/table.html&quot;</span></code>。这个模板呈现表单集的管理表单，然后根据表单的 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/api/#django.forms.Form.as_table\" title=\"django.forms.Form.as_table\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_table()</span></code></a> 方法来呈现表单集中的每个表单。</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_ul\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_ul</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_ul\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>在调用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_ul\" title=\"django.forms.formsets.BaseFormSet.as_ul\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_ul()</span></code></a> 时使用的模板名称。默认情况下，这是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/ul.html&quot;</span></code>。这个模板呈现表单集的管理表单，然后根据表单的 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/api/#django.forms.Form.as_ul\" title=\"django.forms.Form.as_ul\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_ul()</span></code></a> 方法来呈现表单集中的每个表单。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.get_context\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_context</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.get_context\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>返回用于在模板中渲染表单集的上下文。</p>\n<p>可用的上下文：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">formset</span></code>：表单集的实例。</p></li>\n</ul>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.render\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">render</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">template_name</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">context</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">renderer</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.render\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>render 方法被 <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__</span></code> 调用，以及 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_div\" title=\"django.forms.formsets.BaseFormSet.as_div\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_div()</span></code></a>、<a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_p\" title=\"django.forms.formsets.BaseFormSet.as_p\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_p()</span></code></a>、<a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_ul\" title=\"django.forms.formsets.BaseFormSet.as_ul\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_ul()</span></code></a> 和 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_table\" title=\"django.forms.formsets.BaseFormSet.as_table\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_table()</span></code></a> 方法。所有参数都是可选的，将默认为：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code>： <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name\" title=\"django.forms.formsets.BaseFormSet.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code>： 由 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.get_context\" title=\"django.forms.formsets.BaseFormSet.get_context\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context()</span></code></a> 返回的值</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">renderer</span></code>： 由 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.renderer\" title=\"django.forms.formsets.BaseFormSet.renderer\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">renderer</span></code></a> 返回的值</p></li>\n</ul>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_div\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_div</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_div\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><aside class=\"version-note version-added\" data-version=\"4.1\">\n<p class=\"version-note-title\">New in Django 4.1</p></aside>\n<p>使用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_div\" title=\"django.forms.formsets.BaseFormSet.template_name_div\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_div</span></code></a> 模板呈现表单集。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_p\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_p</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_p\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_p\" title=\"django.forms.formsets.BaseFormSet.template_name_p\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_p</span></code></a> 模板渲染表单集。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_table\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_table</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_table\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>使用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_table\" title=\"django.forms.formsets.BaseFormSet.template_name_table\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_table</span></code></a> 模板渲染表单集。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_ul\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_ul</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_ul\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_ul\" title=\"django.forms.formsets.BaseFormSet.template_name_ul\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_ul</span></code></a> 模板渲染表单集。</p>\n</dd></dl>\n\n<p>在视图中使用formset与使用常规的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> 类没有太多不同之处。你唯一需要注意的是确保要在模板中使用管理表单。我们来看一个示例视图：</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</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</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<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">manage_articles</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</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=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">FILES</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># do something with the formset.cleaned_data</span>\n            <span class=\"k\">pass</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</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;manage_articles.html&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;formset&quot;</span><span class=\"p\">:</span> <span class=\"n\">formset</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>模板 <code class=\"docutils literal notranslate\"><span class=\"pre\">manage_articles.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\">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=\"nv\">formset.management_form</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">table</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">form</span> <span class=\"k\">in</span> <span class=\"nv\">formset</span> <span class=\"cp\">%}</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">form</span> <span class=\"cp\">}}</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">table</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>但是对于上面让formset自己处理管理表单，还有个小小的捷径：</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\">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\">table</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{{</span> <span class=\"nv\">formset</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">table</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>上面的内容最终会调用表单集类上的 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.render\" title=\"django.forms.formsets.BaseFormSet.render\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">BaseFormSet.render()</span></code></a> 方法。这将使用 <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name\" title=\"django.forms.formsets.BaseFormSet.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a> 属性指定的模板来渲染表单集。与表单类似，默认情况下，表单集将被渲染为 <code class=\"docutils literal notranslate\"><span class=\"pre\">as_table</span></code>，其他辅助方法 <code class=\"docutils literal notranslate\"><span class=\"pre\">as_p</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">as_ul</span></code> 可用。表单集的渲染可以通过指定 <code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code> 属性来定制，或者更普遍的是通过 <a class=\"reference internal\" href=\"/zh-hans/4.2/ref/forms/renderers/#overriding-built-in-formset-templates\"><span class=\"std std-ref\">覆盖默认模板</span></a>。</p>\n<section id=\"manually-rendered-can-delete-and-can-order\">\n<span id=\"id4\"></span><h3>手动渲染 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code><a class=\"heading-anchor\" href=\"#manually-rendered-can-delete-and-can-order\"><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\">{{</span> <span class=\"pre\">form.DELETE</span> <span class=\"pre\">}}</span></code> 来渲染参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</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\">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=\"nv\">formset.management_form</span> <span class=\"cp\">}}</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">form</span> <span class=\"k\">in</span> <span class=\"nv\">formset</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.title</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.pub_date</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n            <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">formset.can_delete</span> <span class=\"cp\">%}</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.DELETE</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</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\">ul</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\">form</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>同样，如果formset能排序( <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order=True</span></code> )，可以用 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form.ORDER</span> <span class=\"pre\">}}</span></code> 来渲染它。</p>\n</section>\n<section id=\"using-more-than-one-formset-in-a-view\">\n<span id=\"multiple-formsets-in-view\"></span><h3>在视图中使用多个formset<a class=\"heading-anchor\" href=\"#using-more-than-one-formset-in-a-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>你可以在视图中使用多个formset。表单集从表单上借鉴了很多行为。像之前说的，你可以使用参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> 来给formset中表单的字段附上前缀，以避免多个formset的数据传到同一个视图而引起名称冲突。让我们来看下这是如何实现的：</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</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</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<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">BookForm</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">manage_articles</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n    <span class=\"n\">BookFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">BookForm</span><span class=\"p\">)</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=\"n\">article_formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">FILES</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;articles&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">book_formset</span> <span class=\"o\">=</span> <span class=\"n\">BookFormSet</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">FILES</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;books&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">article_formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span> <span class=\"ow\">and</span> <span class=\"n\">book_formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># do something with the cleaned_data on the formsets.</span>\n            <span class=\"k\">pass</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">article_formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;articles&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">book_formset</span> <span class=\"o\">=</span> <span class=\"n\">BookFormSet</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;books&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span>\n        <span class=\"n\">request</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;manage_articles.html&quot;</span><span class=\"p\">,</span>\n        <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;article_formset&quot;</span><span class=\"p\">:</span> <span class=\"n\">article_formset</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;book_formset&quot;</span><span class=\"p\">:</span> <span class=\"n\">book_formset</span><span class=\"p\">,</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n<p>然后您就可以像平时那样渲染表单集。需要指出的是，您需要同时在POST和非POST情况下传递 <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> ，以便它能被正确渲染和处理。</p>\n<p>每个formset的 <a class=\"reference internal\" href=\"#formset-prefix\"><span class=\"std std-ref\">prefix</span></a> 会替换添加到每个字段的 <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">id</span></code> HTML属性的默认 <code class=\"docutils literal notranslate\"><span class=\"pre\">form</span></code> 前缀。</p>\n</section>\n</section>","rootId":"formsets","toc":[{"title":"使用formset的初始数据","anchor":"using-initial-data-with-a-formset","children":[]},{"title":"限制表单的最大数量","anchor":"limiting-the-maximum-number-of-forms","children":[]},{"title":"限制实例化表单的最大数量","anchor":"limiting-the-maximum-number-of-instantiated-forms","children":[]},{"title":"Formset验证","anchor":"formset-validation","children":[{"title":"理解 ManagementForm","anchor":"understanding-the-managementform","children":[]},{"title":"total_form_count 和 initial_form_count","anchor":"total-form-count-and-initial-form-count","children":[]},{"title":"empty_form","anchor":"empty-form","children":[]},{"title":"error_messages","anchor":"error-messages","children":[]},{"title":"自定义formset验证","anchor":"custom-formset-validation","children":[]}]},{"title":"验证formset中表单的数量","anchor":"validating-the-number-of-forms-in-a-formset","children":[{"title":"validate_max","anchor":"validate-max","children":[]},{"title":"validate_min","anchor":"validate-min","children":[]}]},{"title":"处理表单的排序和删除","anchor":"dealing-with-ordering-and-deletion-of-forms","children":[{"title":"can_order","anchor":"can-order","children":[{"title":"ordering_widget","anchor":"ordering-widget","children":[]},{"title":"get_ordering_widget","anchor":"get-ordering-widget","children":[]}]},{"title":"can_delete","anchor":"can-delete","children":[{"title":"deletion_widget","anchor":"deletion-widget","children":[]},{"title":"get_deletion_widget","anchor":"get-deletion-widget","children":[]}]},{"title":"can_delete_extra","anchor":"can-delete-extra","children":[]}]},{"title":"给一个formset添加额外字段","anchor":"adding-additional-fields-to-a-formset","children":[]},{"title":"传递自定义参数到formset表单","anchor":"passing-custom-parameters-to-formset-forms","children":[]},{"title":"自定义formset的前缀","anchor":"customizing-a-formset-s-prefix","children":[]},{"title":"在视图和模板中使用formset","anchor":"using-a-formset-in-views-and-templates","children":[{"title":"手动渲染 can_delete 和 can_order","anchor":"manually-rendered-can-delete-and-can-order","children":[]},{"title":"在视图中使用多个formset","anchor":"using-more-than-one-formset-in-a-view","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/4.2/topics/"},{"docname":"topics/forms/index","title":"使用表单","url":"/zh-hans/4.2/topics/forms/"}],"prev":{"docname":"topics/forms/index","title":"使用表单","url":"/zh-hans/4.2/topics/forms/"},"next":{"docname":"topics/forms/modelforms","title":"从模型创建表单","url":"/zh-hans/4.2/topics/forms/modelforms/"},"formats":{"html":"/zh-hans/4.2/topics/forms/formsets/","markdown":"/zh-hans/4.2/topics/forms/formsets.md","json":"/zh-hans/4.2/topics/forms/formsets.json"},"source":"https://github.com/django/django/blob/stable/4.2.x/docs/topics/forms/formsets.txt","official":"https://docs.djangoproject.com/zh-hans/4.2/topics/forms/formsets/","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"]}