summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorAnders Steinlein <anders@e5r.no>2014-03-05 21:19:40 +0100
committerTim Graham <timograham@gmail.com>2014-05-15 07:25:35 -0400
commit4ef10f245ada0c7d5ae8dc31eebffa63790d40fb (patch)
treedffd7ca06862fa20b5fa0b4528ac8beeecaee9fa /django
parent860d31ac7a3bdd4b27db8b34b110b3d801ddaf8a (diff)
Fixed #17642 -- Added min_num support to modelformsets, inlines, and the admin.
Thanks Stephen Burrows for work on the patch as well. Forwardport of 2914f66983a92fcae55673c517dd8d01e8c238c4 from stable/1.7.x
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/checks.py13
-rw-r--r--django/contrib/admin/options.py6
-rw-r--r--django/contrib/contenttypes/admin.py1
-rw-r--r--django/contrib/contenttypes/forms.py9
-rw-r--r--django/forms/models.py12
5 files changed, 32 insertions, 9 deletions
diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py
index dfe4cd04ec..e49bb8fb6e 100644
--- a/django/contrib/admin/checks.py
+++ b/django/contrib/admin/checks.py
@@ -850,6 +850,7 @@ class InlineModelAdminChecks(BaseModelAdminChecks):
errors.extend(self._check_exclude_of_parent_model(cls, parent_model))
errors.extend(self._check_extra(cls))
errors.extend(self._check_max_num(cls))
+ errors.extend(self._check_min_num(cls))
errors.extend(self._check_formset(cls))
return errors
@@ -909,12 +910,22 @@ class InlineModelAdminChecks(BaseModelAdminChecks):
else:
return []
+ def _check_min_num(self, cls):
+ """ Check that min_num is an integer. """
+
+ if cls.min_num is None:
+ return []
+ elif not isinstance(cls.min_num, int):
+ return must_be('an integer', option='min_num', obj=cls, id='admin.E205')
+ else:
+ return []
+
def _check_formset(self, cls):
""" Check formset is a subclass of BaseModelFormSet. """
if not issubclass(cls.formset, BaseModelFormSet):
return must_inherit_from(parent='BaseModelFormSet', option='formset',
- obj=cls, id='admin.E205')
+ obj=cls, id='admin.E206')
else:
return []
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 016b73d987..2d5a5cf933 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -1706,6 +1706,7 @@ class InlineModelAdmin(BaseModelAdmin):
fk_name = None
formset = BaseInlineFormSet
extra = 3
+ min_num = None
max_num = None
template = None
verbose_name = None
@@ -1738,6 +1739,10 @@ class InlineModelAdmin(BaseModelAdmin):
"""Hook for customizing the number of extra inline forms."""
return self.extra
+ def get_min_num(self, request, obj=None, **kwargs):
+ """Hook for customizing the min number of inline forms."""
+ return self.min_num
+
def get_max_num(self, request, obj=None, **kwargs):
"""Hook for customizing the max number of extra inline forms."""
return self.max_num
@@ -1769,6 +1774,7 @@ class InlineModelAdmin(BaseModelAdmin):
"exclude": exclude,
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
"extra": self.get_extra(request, obj, **kwargs),
+ "min_num": self.get_min_num(request, obj, **kwargs),
"max_num": self.get_max_num(request, obj, **kwargs),
"can_delete": can_delete,
}
diff --git a/django/contrib/contenttypes/admin.py b/django/contrib/contenttypes/admin.py
index 8da6546a21..1938fa7aae 100644
--- a/django/contrib/contenttypes/admin.py
+++ b/django/contrib/contenttypes/admin.py
@@ -119,6 +119,7 @@ class GenericInlineModelAdmin(InlineModelAdmin):
"can_delete": can_delete,
"can_order": False,
"fields": fields,
+ "min_num": self.min_num,
"max_num": self.max_num,
"exclude": exclude
}
diff --git a/django/contrib/contenttypes/forms.py b/django/contrib/contenttypes/forms.py
index 33df7528db..693628d3de 100644
--- a/django/contrib/contenttypes/forms.py
+++ b/django/contrib/contenttypes/forms.py
@@ -56,9 +56,9 @@ def generic_inlineformset_factory(model, form=ModelForm,
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):
+ max_num=None, formfield_callback=None,
+ validate_max=False, for_concrete_model=True,
+ min_num=None, validate_min=False):
"""
Returns a ``GenericInlineFormSet`` for the given kwargs.
@@ -81,7 +81,8 @@ 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)
+ validate_max=validate_max, min_num=min_num,
+ validate_min=validate_min)
FormSet.ct_field = ct_field
FormSet.ct_fk_field = fk_field
FormSet.for_concrete_model = for_concrete_model
diff --git a/django/forms/models.py b/django/forms/models.py
index f1a383fde6..263d3d4340 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -805,7 +805,8 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
formset=BaseModelFormSet, extra=1, can_delete=False,
can_order=False, max_num=None, fields=None, exclude=None,
widgets=None, validate_max=False, localized_fields=None,
- labels=None, help_texts=None, error_messages=None):
+ labels=None, help_texts=None, error_messages=None,
+ min_num=None, validate_min=False):
"""
Returns a FormSet class for the given Django model class.
"""
@@ -823,9 +824,9 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
formfield_callback=formfield_callback,
widgets=widgets, localized_fields=localized_fields,
labels=labels, help_texts=help_texts, error_messages=error_messages)
- FormSet = formset_factory(form, formset, extra=extra, max_num=max_num,
+ FormSet = formset_factory(form, formset, extra=extra, min_num=min_num, max_num=max_num,
can_order=can_order, can_delete=can_delete,
- validate_max=validate_max)
+ validate_min=validate_min, validate_max=validate_max)
FormSet.model = model
return FormSet
@@ -969,7 +970,8 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
fields=None, exclude=None, extra=3, can_order=False,
can_delete=True, max_num=None, formfield_callback=None,
widgets=None, validate_max=False, localized_fields=None,
- labels=None, help_texts=None, error_messages=None):
+ labels=None, help_texts=None, error_messages=None,
+ min_num=None, validate_min=False):
"""
Returns an ``InlineFormSet`` for the given kwargs.
@@ -989,8 +991,10 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
'can_order': can_order,
'fields': fields,
'exclude': exclude,
+ 'min_num': min_num,
'max_num': max_num,
'widgets': widgets,
+ 'validate_min': validate_min,
'validate_max': validate_max,
'localized_fields': localized_fields,
'labels': labels,