{"title":"Formulaires groupés","version":"2.2","locale":"fr","docname":"topics/forms/formsets","url":"/fr/2.2/topics/forms/formsets/","canonical":"https://djangodocs.dev/fr/2.2/topics/forms/formsets/","summary":"class BaseFormSet Lien vers cette définition # Les formulaires groupés sont une couche d’abstraction pour travailler avec plusieurs formulaires sur une même page.…","html":"<h1>Formulaires groupés<a class=\"heading-anchor\" href=\"#formsets\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Les formulaires groupés sont une couche d’abstraction pour travailler avec plusieurs formulaires sur une même page. On peut comparer cela à un tableau de données. Admettons que l’on dispose du formulaire suivant :</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</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</code></pre></div>\n<p>Il peut être souhaitable de permettre à l’utilisateur de créer plusieurs articles à la fois. Pour créer des formulaires groupés à partir d’un formulaire <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleForm</span></code>, voici comment procéder :</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=\"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>Vous avez maintenant créé une classe de formulaires groupés nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleFormSet</span></code>. En créant une instance de cette classe, cela vous donne la possibilité d’effectuer une itération sur les formulaires du groupe et de les afficher tout comme vous le feriez pour un formulaire habituel :</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=\"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=\"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>Comme vous le voyez, un seul formulaire vierge a été affiché. Le nombre de formulaires vierges affichés dépend du paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code>. Par défaut, <a class=\"reference internal\" href=\"/fr/2.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> définit un seul formulaire supplémentaire ; l’exemple suivant crée une classe de formulaires groupés pour afficher deux formulaires vierges :</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=\"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>En itérant sur des formulaires groupés, les formulaires sont affichés dans l’ordre où ils ont été créés. Vous pouvez modifier cet ordre en écrivant une implémentation différente de la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__iter__()</span></code>.</p>\n<p>Il est aussi possible d’accéder aux formulaires groupés par un numéro d’index, ce qui renvoie le formulaire correspondant. Si vous surchargez <code class=\"docutils literal notranslate\"><span class=\"pre\">__iter__</span></code>, il est aussi nécessaire de surcharger <code class=\"docutils literal notranslate\"><span class=\"pre\">__getitem__</span></code> afin de garantir un comportement cohérent.</p>\n<section id=\"using-initial-data-with-a-formset\">\n<span id=\"formsets-initial-data\"></span><h2>Données initiales pour les formulaires groupés<a class=\"heading-anchor\" href=\"#using-initial-data-with-a-formset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les données initiales sont le moteur essentiel qui fait l’intérêt des formulaires groupés. Comme on peut le voir ci-dessus, vous pouvez définir le nombre de formulaires supplémentaires. Cela signifie que vous pouvez indiquer aux formulaires groupés combien de formulaires supplémentaires doivent être affichés en plus des formulaires générés à partir des données initiales. Examinons un exemple plus en détails</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\">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><span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>    <span class=\"p\">{</span><span class=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Django is now open source&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>     <span class=\"s1\">&#39;pub_date&#39;</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\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=\"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>Nous avons maintenant trois formulaires qui s’affichent. Un pour les données initiales que nous lui avons transmises et deux formulaires supplémentaires. Notez également que nous transmettons une liste de dictionnaires comme données initiales.</p>\n<p>SI vous utilisez <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span></code> dans l’affichage de formulaires groupés, vous devez passer la même valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span></code> lors du traitement de ces formulaires au moment de l’envoi des données pour permettre la détection des formulaires modifiés par l’utilisateur. Par exemple, vous pourriez avoir quelque chose comme : <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\">Voir aussi</p>\n<p><a class=\"reference internal\" href=\"/fr/2.2/topics/forms/modelforms/#model-formsets\"><span class=\"std std-ref\">Création de formulaires groupés à partir de modèles avec les formulaires groupés de modèle</span></a>.</p>\n</aside>\n</section>\n<section id=\"limiting-the-maximum-number-of-forms\">\n<span id=\"formsets-max-num\"></span><h2>Restriction du nombre maximum de formulaires<a class=\"heading-anchor\" href=\"#limiting-the-maximum-number-of-forms\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> de <a class=\"reference internal\" href=\"/fr/2.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> donne la possibilité de restreindre le nombre de formulaires que les formulaires groupés vont afficher</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\">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=\"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>Si la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> est plus grande que le nombre d’objets existants dans les données initiales, un maximum de <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> formulaires vierges supplémentaires seront ajoutés au formulaire groupé, tant que le nombre total de formulaires n’excède pas <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>. Par exemple, si <code class=\"docutils literal notranslate\"><span class=\"pre\">extra=2</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num=2</span></code> et que le  formulaire groupé est initialisé avec un élément <code class=\"docutils literal notranslate\"><span class=\"pre\">initial</span></code>, on verra s’afficher un formulaire pour l’élément initial et un formulaire vierge.</p>\n<p>Si le nombre d’éléments dans les données initiales dépasse <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>, tous les formulaires correspondant aux données initiales seront affichés quelle que soit la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> et aucun formulaire supplémentaire ne sera affiché. Par exemple, si <code class=\"docutils literal notranslate\"><span class=\"pre\">extra=3</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num=1</span></code> et que le formulaire groupé est initialisé avec deux éléments, ce sont deux formulaires avec les données initiales qui seront affichés.</p>\n<p>Une valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> (par défaut) place une limite élevée du nombre de formulaires affichés (1000). En pratique, cela équivaut à aucune limite.</p>\n<p>Par défaut, <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> ne s’applique qu’au nombre de formulaires affichés et non pas à la validation. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max=True</span></code> est transmis à <a class=\"reference internal\" href=\"/fr/2.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> s’applique alors à la validation. Voir <a class=\"reference internal\" href=\"#validate-max\"><span class=\"std std-ref\">validate_max</span></a>.</p>\n</section>\n<section id=\"formset-validation\">\n<h2>Validation des formulaires groupés<a class=\"heading-anchor\" href=\"#formset-validation\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La validation des formulaires groupés est presque identique à celle d’un formulaire <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> normal. L’objet de formulaires groupés contient une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">is_valid</span></code> afin de fournir une manière agile de valider tous les formulaires du groupe :</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>\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;1&#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-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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\">True</span>\n</code></pre></div>\n<p>Nous n’avons fourni aucune donnée aux formulaires groupés ce qui aboutit à un formulaire valide. Les formulaires groupés sont assez intelligents pour ne pas prendre en compte des formulaires supplémentaires qui n’ont pas été modifiés. Si nous passons un article non valable :</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=\"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-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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&#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;&#39;</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>Comme on peut le voir, <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.errors</span></code> est une liste composée d’éléments correspondants à chaque formulaire du groupe. La validation s’est faite pour chacun des deux formulaires, et le message d’erreur attendu apparaît pour le second.</p>\n<p>Tout comme pour l’utilisation de formulaires normaux, chaque champ de formulaire groupé peut inclure des attributs HTML tels que <code class=\"docutils literal notranslate\"><span class=\"pre\">maxlength</span></code> pour la validation par le navigateur. Cependant, les champs de formulaires groupés n’incluront pas l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">required</span></code> car cette validation pourrait être incorrecte lors de l’ajout ou de la suppression de formulaires.</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Pour contrôler le nombre d’erreurs dans les formulaires groupés, nous pouvons utiliser la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">total_error_count</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=\"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>Nous pouvons aussi vérifier si les données des formulaires diffèrent des données initiales (c’est-à-dire si le formulaire a été envoyé sans aucune donnée) :</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=\"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;1&#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-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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;&#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;&#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\">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>Rôle du formulaire de gestion (<code class=\"docutils literal notranslate\"><span class=\"pre\">ManagementForm</span></code>)<a class=\"heading-anchor\" href=\"#understanding-the-managementform\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous avez peut-être remarqué les données supplémentaires (<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> et <code class=\"docutils literal notranslate\"><span class=\"pre\">form-MAX_NUM_FORMS</span></code>) qui étaient requises dans les données de formulaires groupés ci-dessus. Ces données sont exigées par le formulaire de gestion. Celui-ci est utilisé par les formulaires groupés pour gérer l’ensemble des formulaires contenus dans le groupe. Si vous ne fournissez pas ces données de gestion, une exception sera générée :</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=\"n\">data</span> <span class=\"o\">=</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;&#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=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">django.forms.utils.ValidationError</span>: <span class=\"n\">[&#39;ManagementForm data is missing or has been tampered with&#39;]</span>\n</code></pre></div>\n<p>Ces données servent à conserver la trace du nombre d’instances de formulaires qui sont affichées. Si vous ajoutez de nouveaux formulaires par JavaScript, il est aussi nécessaire d’incrémenter les champs de comptage de ce formulaire. D’un autre côté, si vous utilisez JavaScript pour permettre la suppression d’objets existants, vous devez alors vous assurer que ceux qui sont supprimés soient correctement marqués comme « à supprimer » en incluant le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">form-#-DELETE</span></code> dans les données d’envoi <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code>. Il est prévu que tous les formulaires soient présents dans les données <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> quoi qu’il arrive.</p>\n<p>Le formulaire de gestion est disponible sous forme d’attribut de l’objet de formulaires groupés. Lorsque vous affichez des formulaires groupés dans un gabarit, vous pouvez inclure toutes les données de gestion en affichant <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">my_formset.management_form</span> <span class=\"pre\">}}</span></code> (en remplaçant le nom de vos formulaires groupés en conséquence).</p>\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> et <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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">BaseFormSet</span></code> possède quelques méthodes étroitement liées aux données <code class=\"docutils literal notranslate\"><span class=\"pre\">total_form_count</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">initial_form_count</span></code> du formulaire de gestion <code class=\"docutils literal notranslate\"><span class=\"pre\">ManagementForm</span></code>.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">total_form_count</span></code> renvoie le nombre total de formulaires du groupe de formulaires. <code class=\"docutils literal notranslate\"><span class=\"pre\">initial_form_count</span></code> renvoie le nombre de formulaires du groupe qui ont été pré-remplis et est également utilisé pour déterminer le nombre de formulaires requis. Vous n’aurez probablement jamais à surcharger l’une de ces méthodes, mais prenez garde à bien comprendre ce qu’elles font si vous deviez le faire.</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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">BaseFormSet</span></code> fournit un attribut supplémentaire <code class=\"docutils literal notranslate\"><span class=\"pre\">empty_form</span></code> qui renvoie une instance de formulaire avec le préfixe <code class=\"docutils literal notranslate\"><span class=\"pre\">__prefix__</span></code> pour faciliter l’utilisation de formulaires dynamiques avec JavaScript.</p>\n</section>\n<section id=\"custom-formset-validation\">\n<h3>Validation personnalisée des formulaires groupés<a class=\"heading-anchor\" href=\"#custom-formset-validation\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les formulaires groupés ont une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">clean</span></code> similaire à celle d’une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code>. C’est là que vous pouvez définir votre propre validation agissant au niveau des formulaires groupés :</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\">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=\"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=\"s1\">&#39;title&#39;</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\">forms</span><span class=\"o\">.</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\">append</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"p\">)</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=\"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-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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&#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;Articles in a set must have distinct titles.&#39;]</span>\n</code></pre></div>\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">clean</span></code> des formulaires groupés est appelée après les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">Form.clean</span></code> des formulaires individuels. Les erreurs produites à ce niveau sont accessibles par la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">non_form_errors()</span></code> sur l’objet des formulaires groupés.</p>\n</section>\n</section>\n<section id=\"validating-the-number-of-forms-in-a-formset\">\n<h2>Validation du nombre de formulaires dans les formulaires groupés<a class=\"heading-anchor\" href=\"#validating-the-number-of-forms-in-a-formset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django fournit plusieurs manières de valider le nombre minimum ou maximum de formulaires soumis. Les applications ayant besoin d’une validation plus adaptée du nombre de formulaires peuvent utiliser la validation personnalisée de formulaires groupés.</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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max=True</span></code> est transmis à <a class=\"reference internal\" href=\"/fr/2.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>, la validation vérifiera également que le nombre de formulaires dans les données reçues moins ceux marqués pour la suppression ne dépasse pas <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-MIN_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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 1 or fewer forms.&#39;]</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max=True</span></code> valide strictement la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>, même si cette valeur a été dépassée en raison d’un nombre de données initiales trop important.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Quelle que soit la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max</span></code>, si le nombre de formulaires dans un jeu de données dépasse <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> de plus de 1000, la validation du formulaire échoue comme si <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_max</span></code> avait été défini ; de plus, seuls les 1000 premiers formulaires dépassant <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> seront validés. Tout le reste est purement ignoré. Il s’agit d’une mesure de protection contre les attaques de remplissage de mémoire employant des requêtes <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> contrefaites.</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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si  <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_min=True</span></code> est passé à <a class=\"reference internal\" href=\"/fr/2.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>,  la validation vérifiera également que le nombre de formulaires dans les données reçues moins ceux marqués pour la suppression est supérieur ou égal à <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-MIN_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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 3 or more forms.&#39;]</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"dealing-with-ordering-and-deletion-of-forms\">\n<h2>Tri et suppression de formulaires<a class=\"heading-anchor\" href=\"#dealing-with-ordering-and-deletion-of-forms\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La méthode <a class=\"reference internal\" href=\"/fr/2.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> fournit deux paramètres facultatifs <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> pour faciliter le tri et la suppression de formulaires dans des formulaires groupés.</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\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Valeur par défaut : <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code></p>\n<p>Ce paramètre permet de créer des formulaires groupés qui peuvent être triés :</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\">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><span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>    <span class=\"p\">{</span><span class=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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\">&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=\"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>Ceci ajoute un champ supplémentaire à chaque formulaire. Ce nouveau champ s’appelle <code class=\"docutils literal notranslate\"><span class=\"pre\">ORDER</span></code> et est de type <code class=\"docutils literal notranslate\"><span class=\"pre\">forms.IntegerField</span></code>. Pour les formulaires générés à partir des données initiales, ces champs reçoivent automatiquement une valeur numérique. Voyons ce qui se passe si l’utilisateur modifie ces valeurs :</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=\"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;3&#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;2&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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;Article #1&#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;2008-05-10&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-0-ORDER&#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-1-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #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;2008-05-11&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-1-ORDER&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;1&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-2-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #3&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-2-pub_date&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;2008-05-01&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-2-ORDER&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;0&#39;</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><span class=\"n\">data</span><span class=\"p\">,</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=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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\">&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=\"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</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\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Valeur par défaut : <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code></p>\n<p>Ce paramètre permet de créer des formulaires groupés où l’on peut choisir des formulaires à supprimer :</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\">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><span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>    <span class=\"p\">{</span><span class=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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\">&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=\"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>Un peu comme pour <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code>, ce paramètre ajoute un nouveau champ <code class=\"docutils literal notranslate\"><span class=\"pre\">DELETE</span></code> de type <code class=\"docutils literal notranslate\"><span class=\"pre\">forms.BooleanField</span></code> à chaque formulaire. Lorsque les données reviennent et que certains de ces champs ont une valeur « vrai », il est possible d’accéder aux formulaires concernés avec <code class=\"docutils literal notranslate\"><span class=\"pre\">deleted_forms</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=\"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;3&#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;2&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-MAX_NUM_FORMS&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#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;Article #1&#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;2008-05-10&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-0-DELETE&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;on&#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;Article #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;2008-05-11&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-1-DELETE&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-2-title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-2-pub_date&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;form-2-DELETE&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</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><span class=\"n\">data</span><span class=\"p\">,</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=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Article #2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pub_date&#39;</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\">&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>Si vous utilisez un <a class=\"reference internal\" href=\"/fr/2.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>, les instances de modèle correspondant aux formulaires supprimés seront supprimées lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.save</span> <span class=\"pre\">()</span></code> sera appelée.</p>\n<p>Si vous appelez <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.save(commit=False)</span></code>, les objets ne seront pas supprimés automatiquement. Vous devrez appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code> pour chacun des <a class=\"reference internal\" href=\"/fr/2.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> afin que la suppression soit effective :</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=\"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</code></pre></div>\n<p>D’autre part, si vous utilisez un <code class=\"docutils literal notranslate\"><span class=\"pre\">FormSet</span></code> simple, c’est à vous de gérer <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.deleted_forms</span></code>, par exemple dans la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> de votre formulaire groupé, car il n’existe pas de notion générale sur ce qu’implique la suppression d’un formulaire.</p>\n</section>\n</section>\n<section id=\"adding-additional-fields-to-a-formset\">\n<h2>Ajout de champs supplémentaires à des formulaires groupés<a class=\"heading-anchor\" href=\"#adding-additional-fields-to-a-formset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>L’ajout de champs supplémentaires aux formulaires groupés est simple à effectuer. La classe de base des formulaires groupés offre une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">add_fields</span></code>. Vous pouvez simplement surcharger cette méthode pour ajouter vos propres champs ou même pour redéfinir les champs/attributs par défaut des champs de tri et de suppression :</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\">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\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=\"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>Transmission de paramètres personnalisés aux formulaires de jeux de formulaires<a class=\"heading-anchor\" href=\"#passing-custom-parameters-to-formset-forms\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il arrive parfois qu’une classe de formulaire accepte des paramètres personnalisés, comme <code class=\"docutils literal notranslate\"><span class=\"pre\">MyArticleForm</span></code>. Vous pouvez transmettre ce paramètre lors de l’instanciation du jeu de formulaires :</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\">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\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=\"s1\">&#39;user&#39;</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>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">form_kwargs</span></code> peut aussi dépendre de l’instance de formulaire spécifique. La classe de base du jeu de formulaires fournit une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_form_kwargs</span></code>. Celle-ci accepte un seul paramètre, l’indice du formulaire dans le jeu de formulaire. Cet indice vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> pour le formulaire vide <a class=\"reference internal\" href=\"#empty-form\"><span class=\"std std-ref\">empty_form</span></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"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=\"s1\">&#39;custom_kwarg&#39;</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</code></pre></div>\n</section>\n<section id=\"customizing-a-formset-s-prefix\">\n<span id=\"formset-prefix\"></span><h2>Personnalisation du préfixe d’un jeu de formulaires<a class=\"heading-anchor\" href=\"#customizing-a-formset-s-prefix\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Dans le rendu HTML, les jeux de formulaires ajoutent un préfixe devant chaque nom de champ. Par défaut, le préfixe est <code class=\"docutils literal notranslate\"><span class=\"pre\">'form'</span></code>, mais il peut être personnalisé à l’aide du paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> du jeu de formulaires.</p>\n<p>Par exemple, dans le cas par défaut, on pourrait voir :</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>Mais avec <code class=\"docutils literal notranslate\"><span class=\"pre\">ArticleFormset(prefix='article')</span></code>, cela deviendra :</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>Ceci est utile lorsqu’on veut utiliser <a class=\"reference internal\" href=\"#multiple-formsets-in-view\"><span class=\"std std-ref\">plus d’un jeu de formulaires dans une vue</span></a>.</p>\n</section>\n<section id=\"using-a-formset-in-views-and-templates\">\n<h2>Utilisation des formulaires groupés dans les vues et les gabarits<a class=\"heading-anchor\" href=\"#using-a-formset-in-views-and-templates\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>L’utilisation de formulaires groupés dans une vue est aussi simple que l’utilisation d’une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> habituelle. La seule chose à laquelle il faut être attentif est de ne pas oublier d’inclure le formulaire de gestion dans le gabarit. Examinons un exemple de vue :</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<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=\"s1\">&#39;POST&#39;</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=\"s1\">&#39;manage_articles.html&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;formset&#39;</span><span class=\"p\">:</span> <span class=\"n\">formset</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>Le gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">manage_articles.html</span></code> pourrait ressembler à ceci :</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>Toutefois, le code ci-dessus peut être légèrement raccourci en laissant les formulaires groupés se charger eux-mêmes du formulaire de gestion :</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>Le résultat du code ci-dessus est que la classe de formulaires groupés va appeler sa méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">as_table</span></code>.</p>\n<section id=\"manually-rendered-can-delete-and-can-order\">\n<span id=\"id4\"></span><h3>Affichage manuel de <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> et <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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous affichez manuellement les champs dans le gabarit, vous pouvez afficher le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code> avec <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">form.DELETE</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\">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>De la même façon, si les formulaires groupés peuvent être triés (<code class=\"docutils literal notranslate\"><span class=\"pre\">can_order=True</span></code>), il est possible d’afficher le champ de tri avec <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>Utilisation de plus d’un objet de formulaires groupés dans une vue<a class=\"heading-anchor\" href=\"#using-more-than-one-formset-in-a-view\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il est possible d’utiliser plus d’un objet de formulaires groupés dans une vue. Les formulaires groupés ont un comportement très semblable à celui des formulaires. Ceci dit, vous pouvez utiliser l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> afin de préfixer les noms de champs des formulaires groupés avec une valeur donnée, ce qui permettra d’envoyer plusieurs ensembles de formulaires groupés à une vue sans conflit de nommage. Voyons un peu comment cela pourrait être fait :</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<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=\"s1\">&#39;POST&#39;</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=\"s1\">&#39;articles&#39;</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=\"s1\">&#39;books&#39;</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=\"s1\">&#39;articles&#39;</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=\"s1\">&#39;books&#39;</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=\"s1\">&#39;manage_articles.html&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;article_formset&#39;</span><span class=\"p\">:</span> <span class=\"n\">article_formset</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;book_formset&#39;</span><span class=\"p\">:</span> <span class=\"n\">book_formset</span><span class=\"p\">,</span>\n    <span class=\"p\">})</span>\n</code></pre></div>\n<p>Les formulaires groupés seraient ensuite affichés comme d’habitude. Il est important de relever que vous devez indiquer <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> dans tous les cas (<code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> ou non), afin que l’affichage et le traitement des données puissent se faire correctement.</p>\n<p>Chaque <a class=\"reference internal\" href=\"#formset-prefix\"><span class=\"std std-ref\">prefix</span></a> de jeu de formulaires remplace le préfixe par défaut <code class=\"docutils literal notranslate\"><span class=\"pre\">form</span></code> qui est ajouté à chaque attribut HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">id</span></code> des champs de formulaire.</p>\n</section>\n</section>","rootId":"formsets","toc":[{"title":"Données initiales pour les formulaires groupés","anchor":"using-initial-data-with-a-formset","children":[]},{"title":"Restriction du nombre maximum de formulaires","anchor":"limiting-the-maximum-number-of-forms","children":[]},{"title":"Validation des formulaires groupés","anchor":"formset-validation","children":[{"title":"Rôle du formulaire de gestion (ManagementForm)","anchor":"understanding-the-managementform","children":[]},{"title":"total_form_count et initial_form_count","anchor":"total-form-count-and-initial-form-count","children":[]},{"title":"empty_form","anchor":"empty-form","children":[]},{"title":"Validation personnalisée des formulaires groupés","anchor":"custom-formset-validation","children":[]}]},{"title":"Validation du nombre de formulaires dans les formulaires groupés","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":"Tri et suppression de formulaires","anchor":"dealing-with-ordering-and-deletion-of-forms","children":[{"title":"can_order","anchor":"can-order","children":[]},{"title":"can_delete","anchor":"can-delete","children":[]}]},{"title":"Ajout de champs supplémentaires à des formulaires groupés","anchor":"adding-additional-fields-to-a-formset","children":[]},{"title":"Transmission de paramètres personnalisés aux formulaires de jeux de formulaires","anchor":"passing-custom-parameters-to-formset-forms","children":[]},{"title":"Personnalisation du préfixe d’un jeu de formulaires","anchor":"customizing-a-formset-s-prefix","children":[]},{"title":"Utilisation des formulaires groupés dans les vues et les gabarits","anchor":"using-a-formset-in-views-and-templates","children":[{"title":"Affichage manuel de can_delete et can_order","anchor":"manually-rendered-can-delete-and-can-order","children":[]},{"title":"Utilisation de plus d’un objet de formulaires groupés dans une vue","anchor":"using-more-than-one-formset-in-a-view","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/2.2/topics/"},{"docname":"topics/forms/index","title":"Utilisation des formulaires","url":"/fr/2.2/topics/forms/"}],"prev":{"docname":"topics/forms/index","title":"Utilisation des formulaires","url":"/fr/2.2/topics/forms/"},"next":{"docname":"topics/forms/modelforms","title":"Création de formulaires à partir de modèles","url":"/fr/2.2/topics/forms/modelforms/"},"formats":{"html":"/fr/2.2/topics/forms/formsets/","markdown":"/fr/2.2/topics/forms/formsets.md","json":"/fr/2.2/topics/forms/formsets.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/topics/forms/formsets.txt","official":"https://docs.djangoproject.com/fr/2.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","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}