summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-08-17 13:34:13 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-08-18 09:37:15 +0200
commit35b03788b0607c1f8d2b64e4fa9e1669b0907ea4 (patch)
treefb040ff5e9a0e3362bb1d1f0b652f1d72273fac4
parent3254991762b49cfbeb8434842c19bbbad87cd9c6 (diff)
Refs #9061 -- Allowed GenericInlineFormSet to disable deleting extra forms.
Follow up to 162765d6c3182e36095d29543e21b44b908625fc.
-rw-r--r--django/contrib/contenttypes/forms.py4
-rw-r--r--docs/ref/contrib/contenttypes.txt4
-rw-r--r--docs/releases/3.2.txt5
-rw-r--r--tests/generic_relations/test_forms.py24
4 files changed, 33 insertions, 4 deletions
diff --git a/django/contrib/contenttypes/forms.py b/django/contrib/contenttypes/forms.py
index ce1c361b6c..92a58d49f8 100644
--- a/django/contrib/contenttypes/forms.py
+++ b/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
diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt
index 6cc0033132..28a2e40819 100644
--- a/docs/ref/contrib/contenttypes.txt
+++ b/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
diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt
index 1acea66cff..3a55edb591 100644
--- a/docs/releases/3.2.txt
+++ b/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`
~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/generic_relations/test_forms.py b/tests/generic_relations/test_forms.py
index 1a05681711..f5e76fd3f5 100644
--- a/tests/generic_relations/test_forms.py
+++ b/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)