{"title":"Formulaires groupés","version":"6.1","locale":"fr","docname":"topics/forms/formsets","url":"/fr/6.1/topics/forms/formsets/","canonical":"https://djangodocs.dev/fr/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">forms</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ArticleForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">()</span>\n<span class=\"gp\">... </span>    <span class=\"n\">pub_date</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n</code></pre></div>\n<p>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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/div&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/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">extra</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Formsets can be iterated and indexed, accessing forms in the order they were\ncreated. You can reorder the forms by overriding the default\n<a class=\"reference external\" href=\"https://docs.python.org/3/reference/datamodel.html#object.__iter__\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">__iter__()</span></code></a> and <a class=\"reference external\" href=\"https://docs.python.org/3/reference/datamodel.html#object.__getitem__\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">__getitem__()</span></code></a> methods if needed.\n(For more information on implementing these methods, see the\n<a class=\"reference external\" href=\"https://docs.python.org/3/glossary.html#term-sequence\" title=\"(disponible dans Python v3.14)\"><span class=\"xref std std-term\">Python documentation on sequences</span></a>.)</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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">extra</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span>\n<span class=\"gp\">... </span>            <span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Django is now open source&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>            <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">today</span><span class=\"p\">(),</span>\n<span class=\"gp\">... </span>        <span class=\"p\">}</span>\n<span class=\"gp\">... </span>    <span class=\"p\">]</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; value=&quot;2023-02-11&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-title&quot; id=&quot;id_form-1-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-1-pub_date&quot; id=&quot;id_form-1-pub_date&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-title&quot; id=&quot;id_form-2-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-pub_date&quot; id=&quot;id_form-2-pub_date&quot;&gt;&lt;/div&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/6.1/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/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">extra</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">max_num</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/div&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/6.1/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=\"limiting-the-maximum-number-of-instantiated-forms\">\n<span id=\"formsets-absolute-max\"></span><h2>Restriction du nombre maximum de formulaires instanciés<a class=\"heading-anchor\" href=\"#limiting-the-maximum-number-of-instantiated-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\">absolute_max</span></code> de <a class=\"reference internal\" href=\"/fr/6.1/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> permet de limiter le nombre de formulaires pouvant être instanciés lors de la soumission de données <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code>. Ceci protège contre les attaques par épuisement de la mémoire qui utilisent des requêtes <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> trafiquées :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms.formsets</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">absolute_max</span><span class=\"o\">=</span><span class=\"mi\">1500</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1501&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">forms</span><span class=\"p\">)</span>\n<span class=\"go\">1500</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Please submit at most 1000 forms.&#39;]</span>\n</code></pre></div>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, la valeur par défaut est de <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span> <span class=\"pre\">+</span> <span class=\"pre\">1000</span></code> (si <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, sa valeur par défaut est de <code class=\"docutils literal notranslate\"><span class=\"pre\">2000</span></code>).</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> est plus petit que <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>, une erreur <code class=\"docutils literal notranslate\"><span class=\"pre\">ValueError</span></code> est générée.</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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">True</span>\n</code></pre></div>\n<p>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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1904-06-16&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>  <span class=\"c1\"># &lt;-- this date is missing but required</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {&#39;pub_date&#39;: [&#39;This field is required.&#39;]}]</span>\n</code></pre></div>\n<p>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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Using the previous example</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {&#39;pub_date&#39;: [&#39;This field is required.&#39;]}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span><span class=\"p\">)</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">total_error_count</span><span class=\"p\">()</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p>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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">has_changed</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n</code></pre></div>\n<section id=\"understanding-the-managementform\">\n<span id=\"id1\"></span><h3>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>) 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, le jeu de formulaires ne sera pas valide :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n</code></pre></div>\n<p>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<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>En plus des champs <code class=\"docutils literal notranslate\"><span class=\"pre\">form-TOTAL_FORMS</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">form-INITIAL_FORMS</span></code> montrés dans ces exemples, le formulaire de gestion inclut aussi les champs <code class=\"docutils literal notranslate\"><span class=\"pre\">form-MIN_NUM_FORMS</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">form-MAX_NUM_FORMS</span></code>. Ils sont produits avec le reste du formulaire de gestion, mais seulement utiles pour le code côté client. Ces champs ne sont pas obligatoires et ne sont donc pas affichés dans l’exemple de données <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code>.</p>\n</aside>\n</section>\n<section id=\"total-form-count-and-initial-form-count\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">total_form_count</span></code> 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=\"error-messages\">\n<span id=\"formsets-error-messages\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">error_messages</span></code><a class=\"heading-anchor\" href=\"#error-messages\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’argument <code class=\"docutils literal notranslate\"><span class=\"pre\">error_messages</span></code> vous permet de surcharger les messages par défaut que le jeu de formulaires va produire. Passez un dictionnaire dont les clés correspondent aux messages d’erreur que vous souhaitez surcharger. Ces clés sont : <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">'missing_management_form'</span></code>. Les messages d’erreur <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> peuvent contenir <code class=\"docutils literal notranslate\"><span class=\"pre\">%(num)d</span></code>, ce qui sera remplacé respectivement par <code class=\"docutils literal notranslate\"><span class=\"pre\">min_num</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">max_num</span></code>.</p>\n<p>Par exemple, voici le message d’erreur par défaut lorsque le formulaire de gestion est manquant :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">({})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;ManagementForm data is missing or has been tampered with. Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. You may need to file a bug report if the issue persists.&#39;]</span>\n</code></pre></div>\n<p>Et voici un message d’erreur personnalisé :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"p\">{},</span> <span class=\"n\">error_messages</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;missing_management_form&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Sorry, something went wrong.&quot;</span><span class=\"p\">}</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Sorry, something went wrong.&#39;]</span>\n</code></pre></div>\n</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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ValidationError</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">clean</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span><span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;Checks that no two articles have the same title.&quot;&quot;&quot;</span>\n<span class=\"gp\">... </span>        <span class=\"k\">if</span> <span class=\"nb\">any</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">errors</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>            <span class=\"c1\"># Don&#39;t bother validating the formset unless each form is valid on its own</span>\n<span class=\"gp\">... </span>            <span class=\"k\">return</span>\n<span class=\"gp\">... </span>        <span class=\"n\">titles</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n<span class=\"gp\">... </span>        <span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">forms</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">can_delete</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_should_delete_form</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>                <span class=\"k\">continue</span>\n<span class=\"gp\">... </span>            <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>            <span class=\"k\">if</span> <span class=\"n\">title</span> <span class=\"ow\">in</span> <span class=\"n\">titles</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>                <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Articles in a set must have distinct titles.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>            <span class=\"n\">titles</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1904-06-16&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1912-06-23&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Articles in a set must have distinct titles.&#39;]</span>\n</code></pre></div>\n<p>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<p>Les erreurs non liées au formulaire sont produites avec une classe supplémentaire <code class=\"docutils literal notranslate\"><span class=\"pre\">nonform</span></code> pour aider à les distinguer des autres erreurs spécifiques au formulaire. Par exemple, <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">formset.non_form_errors</span> <span class=\"pre\">}}</span></code> donnera quelque chose comme :</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;errorlist nonform&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Articles in a set must have distinct titles.<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"validating-the-number-of-forms-in-a-formset\">\n<h2>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/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">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=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1904-06-16&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test 2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1912-06-23&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Please submit at most 1 form.&#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<p>Le message d’erreur peut être personnalisé en passant le message <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_many_forms'</span></code> dans l’argument <a class=\"reference internal\" href=\"#formsets-error-messages\"><span class=\"std std-ref\">error_messages</span></a>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>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\">absolute_max</span></code>, 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 <code class=\"docutils literal notranslate\"><span class=\"pre\">absolute_max</span></code> premiers formulaires 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. Voir <a class=\"reference internal\" href=\"#formsets-absolute-max\"><span class=\"std std-ref\">Restriction du nombre maximum de formulaires instanciés</span></a>.</p>\n</aside>\n</section>\n<section id=\"validate-min\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">validate_min</span></code><a class=\"heading-anchor\" href=\"#validate-min\"><span class=\"visually-hidden\">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/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">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=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1904-06-16&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Test 2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1912-06-23&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span>\n<span class=\"go\">False</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">errors</span>\n<span class=\"go\">[{}, {}]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">non_form_errors</span><span class=\"p\">()</span>\n<span class=\"go\">[&#39;Please submit at least 3 forms.&#39;]</span>\n</code></pre></div>\n<p>Le message d’erreur peut être personnalisé en passant le message <code class=\"docutils literal notranslate\"><span class=\"pre\">'too_few_forms'</span></code> dans l’argument <a class=\"reference internal\" href=\"#formsets-error-messages\"><span class=\"std std-ref\">error_messages</span></a>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Quelle que soit la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_min</span></code>, si un jeu de formulaires ne contient aucune donnée, <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span> <span class=\"pre\">+</span> <span class=\"pre\">min_num</span></code> formulaires vides seront affichés.</p>\n</aside>\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/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">can_order</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">]</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-ORDER&quot;&gt;Order:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-title&quot;&gt;Title:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-pub_date&quot;&gt;Pub date:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-ORDER&quot;&gt;Order:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-title&quot; id=&quot;id_form-2-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-pub_date&quot; id=&quot;id_form-2-pub_date&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-ORDER&quot;&gt;Order:&lt;/label&gt;&lt;input type=&quot;number&quot; name=&quot;form-2-ORDER&quot; id=&quot;id_form-2-ORDER&quot;&gt;&lt;/div&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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;3&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-10&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-ORDER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-11&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-ORDER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #3&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-01&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-ORDER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">data</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">],</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">ordered_forms</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">{&#39;title&#39;: &#39;Article #3&#39;, &#39;pub_date&#39;: datetime.date(2008, 5, 1), &#39;ORDER&#39;: 0}</span>\n<span class=\"go\">{&#39;title&#39;: &#39;Article #2&#39;, &#39;pub_date&#39;: datetime.date(2008, 5, 11), &#39;ORDER&#39;: 1}</span>\n<span class=\"go\">{&#39;title&#39;: &#39;Article #1&#39;, &#39;pub_date&#39;: datetime.date(2008, 5, 10), &#39;ORDER&#39;: 2}</span>\n</code></pre></div>\n<p>Brut\n<a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet\" title=\"django.forms.formsets.BaseFormSet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseFormSet</span></code></a> fournit également un attribut <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.ordering_widget\" title=\"django.forms.formsets.BaseFormSet.ordering_widget\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">ordering_widget</span></code></a> et une méthode <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.get_ordering_widget\" title=\"django.forms.formsets.BaseFormSet.get_ordering_widget\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_ordering_widget()</span></code></a> qui permet de contrôler le composant utilisé avec <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.can_order\" title=\"django.forms.formsets.BaseFormSet.can_order\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">can_order</span></code></a>.</p>\n<section id=\"ordering-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">ordering_widget</span></code><a class=\"heading-anchor\" href=\"#ordering-widget\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.ordering_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">ordering_widget</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.ordering_widget\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Par défaut : <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/widgets/#django.forms.NumberInput\" title=\"django.forms.NumberInput\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">NumberInput</span></code></a></p>\n<p>Définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">ordering_widget</span></code> pour indiquer la classe de composant à utiliser avec <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ordering_widget</span> <span class=\"o\">=</span> <span class=\"n\">HiddenInput</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_order</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"get-ordering-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">get_ordering_widget</span></code><a class=\"heading-anchor\" href=\"#get-ordering-widget\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.get_ordering_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_ordering_widget</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.get_ordering_widget\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Surchargez <code class=\"docutils literal notranslate\"><span class=\"pre\">get_ordering_widget()</span></code> si vous avez besoin de fournir une instance de composant à utiliser avec <code class=\"docutils literal notranslate\"><span class=\"pre\">can_order</span></code>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_ordering_widget</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"n\">HiddenInput</span><span class=\"p\">(</span><span class=\"n\">attrs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ordering&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_order</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"can-delete\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code><a class=\"heading-anchor\" href=\"#can-delete\"><span class=\"visually-hidden\">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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">can_delete</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">]</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-DELETE&quot;&gt;Delete:&lt;/label&gt;&lt;input type=&quot;checkbox&quot; name=&quot;form-0-DELETE&quot; id=&quot;id_form-0-DELETE&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-title&quot;&gt;Title:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-pub_date&quot;&gt;Pub date:&lt;/label&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;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-1-DELETE&quot;&gt;Delete:&lt;/label&gt;&lt;input type=&quot;checkbox&quot; name=&quot;form-1-DELETE&quot; id=&quot;id_form-1-DELETE&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-title&quot; id=&quot;id_form-2-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-2-pub_date&quot; id=&quot;id_form-2-pub_date&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-2-DELETE&quot;&gt;Delete:&lt;/label&gt;&lt;input type=&quot;checkbox&quot; name=&quot;form-2-DELETE&quot; id=&quot;id_form-2-DELETE&quot;&gt;&lt;/div&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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-TOTAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;3&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-INITIAL_FORMS&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-10&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-0-DELETE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;on&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2008-05-11&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-1-DELETE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-pub_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;form-2-DELETE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">}</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">data</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">[</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>        <span class=\"p\">{</span><span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Article #2&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pub_date&quot;</span><span class=\"p\">:</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">date</span><span class=\"p\">(</span><span class=\"mi\">2008</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">)},</span>\n<span class=\"gp\">... </span>    <span class=\"p\">],</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">[</span><span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span> <span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">deleted_forms</span><span class=\"p\">]</span>\n<span class=\"go\">[{&#39;title&#39;: &#39;Article #1&#39;, &#39;pub_date&#39;: datetime.date(2008, 5, 10), &#39;DELETE&#39;: True}]</span>\n</code></pre></div>\n<p>Si vous utilisez un <a class=\"reference internal\" href=\"/fr/6.1/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/6.1/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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">instances</span> <span class=\"o\">=</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">commit</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">obj</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">deleted_objects</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n</code></pre></div>\n<p>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<p><a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet\" title=\"django.forms.formsets.BaseFormSet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseFormSet</span></code></a> fournit également un attribut <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.deletion_widget\" title=\"django.forms.formsets.BaseFormSet.deletion_widget\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">deletion_widget</span></code></a> et une méthode <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.get_deletion_widget\" title=\"django.forms.formsets.BaseFormSet.get_deletion_widget\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_deletion_widget()</span></code></a> qui permet de contrôler le composant utilisé avec <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.can_delete\" title=\"django.forms.formsets.BaseFormSet.can_delete\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">can_delete</span></code></a>.</p>\n<section id=\"deletion-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">deletion_widget</span></code><a class=\"heading-anchor\" href=\"#deletion-widget\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.deletion_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">deletion_widget</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.deletion_widget\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Par défaut : <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/widgets/#django.forms.CheckboxInput\" title=\"django.forms.CheckboxInput\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CheckboxInput</span></code></a></p>\n<p>Définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">deletion_widget</span></code> pour indiquer la classe de composant à utiliser avec <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"n\">deletion_widget</span> <span class=\"o\">=</span> <span class=\"n\">HiddenInput</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_delete</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"get-deletion-widget\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">get_deletion_widget</span></code><a class=\"heading-anchor\" href=\"#get-deletion-widget\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.get_deletion_widget\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_deletion_widget</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.get_deletion_widget\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Surchargez <code class=\"docutils literal notranslate\"><span class=\"pre\">get_deletion_widget()</span></code> si vous avez besoin de fournir une instance de composant à utiliser avec <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete</span></code>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span><span class=\"p\">,</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_deletion_widget</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"n\">HiddenInput</span><span class=\"p\">(</span><span class=\"n\">attrs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;deletion&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">,</span> <span class=\"n\">can_delete</span><span class=\"o\">=</span><span class=\"kc\">True</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"can-delete-extra\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete_extra</span></code><a class=\"heading-anchor\" href=\"#can-delete-extra\"><span class=\"visually-hidden\">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_extra\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">can_delete_extra</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.can_delete_extra\"><span class=\"visually-hidden\">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\">True</span></code></p>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete=True</span></code>, la définition de <code class=\"docutils literal notranslate\"><span class=\"pre\">can_delete_extra=False</span></code> enlève la possibilité de supprimer les formulaires supplémentaires.</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 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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">add_fields</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">form</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">add_fields</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>        <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">fields</span><span class=\"p\">[</span><span class=\"s2\">&quot;my_field&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">form</span> <span class=\"ow\">in</span> <span class=\"n\">formset</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-title&quot;&gt;Title:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-title&quot; id=&quot;id_form-0-title&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-pub_date&quot;&gt;Pub date:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-pub_date&quot; id=&quot;id_form-0-pub_date&quot;&gt;&lt;/div&gt;</span>\n<span class=\"go\">&lt;div&gt;&lt;label for=&quot;id_form-0-my_field&quot;&gt;My field:&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;form-0-my_field&quot; id=&quot;id_form-0-my_field&quot;&gt;&lt;/div&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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ArticleForm</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyArticleForm</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"n\">user</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"n\">user</span>\n<span class=\"gp\">... </span>        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">MyArticleForm</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">form_kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;user&quot;</span><span class=\"p\">:</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>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=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseFormSet</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">formset_factory</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">BaseFormSet</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_form_kwargs</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"n\">kwargs</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_form_kwargs</span><span class=\"p\">(</span><span class=\"n\">index</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>        <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s2\">&quot;custom_kwarg&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">index</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"n\">kwargs</span>\n<span class=\"gp\">...</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">MyArticleForm</span><span class=\"p\">,</span> <span class=\"n\">formset</span><span class=\"o\">=</span><span class=\"n\">BaseArticleFormSet</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"customizing-a-formset-s-prefix\">\n<span id=\"formset-prefix\"></span><h2>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<span id=\"formset-rendering\"></span><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>Les jeux de formulaires possèdent les attributs et méthodes suivantes associées à leur rendu :</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.renderer\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">renderer</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.renderer\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Indique le <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/renderers/\"><span class=\"doc\">moteur de rendu</span></a> à utiliser pour le jeu de formulaires. Contient par défaut le moteur de rendu défini dans le réglage <a class=\"reference internal\" href=\"/fr/6.1/ref/settings/#std-setting-FORM_RENDERER\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">FORM_RENDERER</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le nom du gabarit produit si le jeu de formulaire est forcé à une chaîne, par ex. via <code class=\"docutils literal notranslate\"><span class=\"pre\">print(formset)</span></code> ou dans un gabarit via <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">formset</span> <span class=\"pre\">}}</span></code>.</p>\n<p>Par défaut, une propriété renvoyant la valeur <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/renderers/#django.forms.renderers.BaseRenderer.formset_template_name\" title=\"django.forms.renderers.BaseRenderer.formset_template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">formset_template_name</span></code></a> du producteur. Vous pouvez la définir à un nom de gabarit afin de la surcharger pour une classe de jeu de formulaires particulière.</p>\n<p>Ce gabarit sera utilisé pour produire le formulaire de gestion du jeu de formulaires, puis chaque formulaire du jeu en respectant le gabarit défini par l’attribut <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/api/#django.forms.Form.template_name\" title=\"django.forms.Form.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a> du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_div\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_div</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_div\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le nom du gabarit à utiliser lors de l’appel à <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_div\" title=\"django.forms.formsets.BaseFormSet.as_div\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_div()</span></code></a>. Par défaut, il s’agit de <code class=\"docutils literal notranslate\"><span class=\"pre\">'django/forms/formsets/div.html'</span></code>. Ce gabarit produit le formulaire de gestion du jeu de formulaires, puis chaque formulaire du jeu en respectant la méthode <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/api/#django.forms.Form.as_div\" title=\"django.forms.Form.as_div\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_div()</span></code></a> du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_p\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_p</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_p\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le nom du gabarit à utiliser lors de l’appel à <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_p\" title=\"django.forms.formsets.BaseFormSet.as_p\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_p()</span></code></a>. Par défaut, il s’agit de <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/p.html&quot;</span></code>. Ce gabarit produit le formulaire de gestion du jeu de formulaires, puis chaque formulaire du jeu en respectant la méthode <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/api/#django.forms.Form.as_p\" title=\"django.forms.Form.as_p\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_p()</span></code></a> du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_table\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_table</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_table\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le nom du gabarit à utiliser lors de l’appel à <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_table\" title=\"django.forms.formsets.BaseFormSet.as_table\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_table()</span></code></a>. Par défaut, il s’agit de <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/table.html&quot;</span></code>. Ce gabarit produit le formulaire de gestion du jeu de formulaires, puis chaque formulaire du jeu en respectant la méthode <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/api/#django.forms.Form.as_table\" title=\"django.forms.Form.as_table\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_table()</span></code></a> du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.template_name_ul\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">template_name_ul</span></span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.template_name_ul\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le nom du gabarit à utiliser lors de l’appel à <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_ul\" title=\"django.forms.formsets.BaseFormSet.as_ul\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_ul()</span></code></a>. Par défaut, il s’agit de <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django/forms/formsets/ul.html&quot;</span></code>. Ce gabarit produit le formulaire de gestion du jeu de formulaires, puis chaque formulaire du jeu en respectant la méthode <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/api/#django.forms.Form.as_ul\" title=\"django.forms.Form.as_ul\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_ul()</span></code></a> du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.get_context\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_context</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.get_context\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie le contexte pour la production du jeu de formulaires dans un gabarit.</p>\n<p>Le contexte disponible est :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">formset</span></code>: l’instance du jeu de formulaire.</p></li>\n</ul>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.render\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">render</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">template_name</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">context</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">renderer</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.render\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>La méthode de production est appelée par <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__</span></code> ainsi que par les méthodes <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_div\" title=\"django.forms.formsets.BaseFormSet.as_div\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_div()</span></code></a>, <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_p\" title=\"django.forms.formsets.BaseFormSet.as_p\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_p()</span></code></a>, <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_ul\" title=\"django.forms.formsets.BaseFormSet.as_ul\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_ul()</span></code></a> et <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.as_table\" title=\"django.forms.formsets.BaseFormSet.as_table\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_table()</span></code></a>. Tous les arguments sont facultatifs et valent par défaut :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code>: <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name\" title=\"django.forms.formsets.BaseFormSet.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code>: la valeur renvoyée par <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.get_context\" title=\"django.forms.formsets.BaseFormSet.get_context\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context()</span></code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">renderer</span></code>: la valeur renvoyée par <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.renderer\" title=\"django.forms.formsets.BaseFormSet.renderer\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">renderer</span></code></a></p></li>\n</ul>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_div\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_div</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_div\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit le jeu de formulaires avec le gabarit <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_div\" title=\"django.forms.formsets.BaseFormSet.template_name_div\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_div</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_p\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_p</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_p\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit le jeu de formulaires avec le gabarit <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_p\" title=\"django.forms.formsets.BaseFormSet.template_name_p\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_p</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_table\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_table</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_table\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit le jeu de formulaires avec le gabarit <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_table\" title=\"django.forms.formsets.BaseFormSet.template_name_table\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_table</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.forms.formsets.BaseFormSet.as_ul\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">BaseFormSet.</span></span><span class=\"sig-name descname\"><span class=\"pre\">as_ul</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.forms.formsets.BaseFormSet.as_ul\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit le jeu de formulaires avec le gabarit <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name_ul\" title=\"django.forms.formsets.BaseFormSet.template_name_ul\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_ul</span></code></a>.</p>\n</dd></dl>\n\n<p>L’utilisation de formulaires groupés dans une vue n’est pas très différent de 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\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">manage_articles</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">method</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;POST&quot;</span><span class=\"p\">:</span>\n        <span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">FILES</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># do something with the formset.cleaned_data</span>\n            <span class=\"k\">pass</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;manage_articles.html&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;formset&quot;</span><span class=\"p\">:</span> <span class=\"n\">formset</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>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 code ci-dessus aboutit à l’appel de la méthode <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.render\" title=\"django.forms.formsets.BaseFormSet.render\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">BaseFormSet.render()</span></code></a> de la classe du jeu de formulaires. Ceci produit le jeu de formulaires en utilisant le gabarit défini par l’attribut <a class=\"reference internal\" href=\"#django.forms.formsets.BaseFormSet.template_name\" title=\"django.forms.formsets.BaseFormSet.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a>. Tout comme pour les formulaires, le jeu de formulaires est produit avec <code class=\"docutils literal notranslate\"><span class=\"pre\">as_div</span></code> par défaut, mais les méthodes utilitaires <code class=\"docutils literal notranslate\"><span class=\"pre\">as_p</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">as_ul</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">as_table</span></code> sont aussi disponibles. La production du jeu de formulaires peut être personnalisée en spécifiant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code> ou plus généralement en <a class=\"reference internal\" href=\"/fr/6.1/ref/forms/renderers/#overriding-built-in-formset-templates\"><span class=\"std std-ref\">surchargeant le gabarit par défaut</span></a>.</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\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">manage_articles</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">ArticleFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">ArticleForm</span><span class=\"p\">)</span>\n    <span class=\"n\">BookFormSet</span> <span class=\"o\">=</span> <span class=\"n\">formset_factory</span><span class=\"p\">(</span><span class=\"n\">BookForm</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">method</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;POST&quot;</span><span class=\"p\">:</span>\n        <span class=\"n\">article_formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">FILES</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;articles&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">book_formset</span> <span class=\"o\">=</span> <span class=\"n\">BookFormSet</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">FILES</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;books&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">article_formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">()</span> <span class=\"ow\">and</span> <span class=\"n\">book_formset</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># do something with the cleaned_data on the formsets.</span>\n            <span class=\"k\">pass</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">article_formset</span> <span class=\"o\">=</span> <span class=\"n\">ArticleFormSet</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;articles&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">book_formset</span> <span class=\"o\">=</span> <span class=\"n\">BookFormSet</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;books&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span>\n        <span class=\"n\">request</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;manage_articles.html&quot;</span><span class=\"p\">,</span>\n        <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;article_formset&quot;</span><span class=\"p\">:</span> <span class=\"n\">article_formset</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;book_formset&quot;</span><span class=\"p\">:</span> <span class=\"n\">book_formset</span><span class=\"p\">,</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n<p>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":"Restriction du nombre maximum de formulaires instanciés","anchor":"limiting-the-maximum-number-of-instantiated-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":"error_messages","anchor":"error-messages","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":"ordering_widget","anchor":"ordering-widget","children":[]},{"title":"get_ordering_widget","anchor":"get-ordering-widget","children":[]}]},{"title":"can_delete","anchor":"can-delete","children":[{"title":"deletion_widget","anchor":"deletion-widget","children":[]},{"title":"get_deletion_widget","anchor":"get-deletion-widget","children":[]}]},{"title":"can_delete_extra","anchor":"can-delete-extra","children":[]}]},{"title":"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/6.1/topics/"},{"docname":"topics/forms/index","title":"Utilisation des formulaires","url":"/fr/6.1/topics/forms/"}],"prev":{"docname":"topics/forms/index","title":"Utilisation des formulaires","url":"/fr/6.1/topics/forms/"},"next":{"docname":"topics/forms/modelforms","title":"Création de formulaires à partir de modèles","url":"/fr/6.1/topics/forms/modelforms/"},"formats":{"html":"/fr/6.1/topics/forms/formsets/","markdown":"/fr/6.1/topics/forms/formsets.md","json":"/fr/6.1/topics/forms/formsets.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/forms/formsets.txt","official":"https://docs.djangoproject.com/fr/6.1/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","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}