Browse Source

Refs #9061 -- Allowed GenericInlineFormSet to disable deleting extra forms.

Follow up to 162765d6c3182e36095d29543e21b44b908625fc.
Mariusz Felisiak 4 năm trước cách đây
mục cha
commit
35b03788b0

+ 2 - 2
django/contrib/contenttypes/forms.py

@@ -57,7 +57,7 @@ def generic_inlineformset_factory(model, form=ModelForm,
                                   max_num=None, formfield_callback=None,
                                   validate_max=False, for_concrete_model=True,
                                   min_num=None, validate_min=False,
-                                  absolute_max=None):
+                                  absolute_max=None, can_delete_extra=True):
     """
     Return a ``GenericInlineFormSet`` for the given kwargs.
 
@@ -76,7 +76,7 @@ def generic_inlineformset_factory(model, form=ModelForm,
         formset=formset, extra=extra, can_delete=can_delete,
         can_order=can_order, fields=fields, exclude=exclude, max_num=max_num,
         validate_max=validate_max, min_num=min_num, validate_min=validate_min,
-        absolute_max=absolute_max,
+        absolute_max=absolute_max, can_delete_extra=can_delete_extra,
     )
     FormSet.ct_field = ct_field
     FormSet.ct_fk_field = fk_field

+ 2 - 2
docs/ref/contrib/contenttypes.txt

@@ -466,7 +466,7 @@ The :mod:`django.contrib.contenttypes.forms` module provides:
 
 .. class:: BaseGenericInlineFormSet
 
-.. function:: generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field="content_type", fk_field="object_id", fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True, min_num=None, validate_min=False, absolute_max=None)
+.. function:: generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field="content_type", fk_field="object_id", fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True, min_num=None, validate_min=False, absolute_max=None, can_delete_extra=True)
 
     Returns a ``GenericInlineFormSet`` using
     :func:`~django.forms.models.modelformset_factory`.
@@ -483,7 +483,7 @@ The :mod:`django.contrib.contenttypes.forms` module provides:
 
     .. versionchanged:: 3.2
 
-        The ``absolute_max`` argument was added.
+        The ``absolute_max`` and ``can_delete_extra`` arguments were added.
 
 .. module:: django.contrib.contenttypes.admin
 

+ 5 - 0
docs/releases/3.2.txt

@@ -90,6 +90,11 @@ Minor features
   allows customizing the maximum number of forms that can be instantiated when
   supplying ``POST`` data. See :ref:`formsets-absolute-max` for more details.
 
+* The new ``can_delete_extra`` argument for
+  :func:`~django.contrib.contenttypes.forms.generic_inlineformset_factory`
+  allows removal of the option to delete extra forms. See
+  :attr:`~.BaseFormSet.can_delete_extra` for more information.
+
 :mod:`django.contrib.gis`
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 24 - 0
tests/generic_relations/test_forms.py

@@ -271,3 +271,27 @@ id="id_generic_relations-taggeditem-content_type-object_id-1-id"></p>""" % tagge
             formset.non_form_errors(),
             ['Please submit 20 or fewer forms.'],
         )
+
+    def test_can_delete_extra(self):
+        GenericFormSet = generic_inlineformset_factory(
+            TaggedItem,
+            can_delete=True,
+            can_delete_extra=True,
+            extra=2,
+        )
+        formset = GenericFormSet()
+        self.assertEqual(len(formset), 2)
+        self.assertIn('DELETE', formset.forms[0].fields)
+        self.assertIn('DELETE', formset.forms[1].fields)
+
+    def test_disable_delete_extra(self):
+        GenericFormSet = generic_inlineformset_factory(
+            TaggedItem,
+            can_delete=True,
+            can_delete_extra=False,
+            extra=2,
+        )
+        formset = GenericFormSet()
+        self.assertEqual(len(formset), 2)
+        self.assertNotIn('DELETE', formset.forms[0].fields)
+        self.assertNotIn('DELETE', formset.forms[1].fields)