Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #18388 - Added InlineModelAdmin.get_max_num hook.

Thanks d.willy.c.c@ for the suggestion and Melevir and Areski Belaid for work
on the patch.
  • Loading branch information...
commit 61524b09cfa3b51643d0e79cbf0e1e08ede357ae 1 parent 07a73a2
@timgraham timgraham authored
View
6 django/contrib/admin/options.py
@@ -1516,6 +1516,10 @@ def get_extra(self, request, obj=None, **kwargs):
"""Hook for customizing the number of extra inline forms."""
return self.extra
+ def get_max_num(self, request, obj=None, **kwargs):
+ """Hook for customizing the max number of extra inline forms."""
+ return self.max_num
+
def get_formset(self, request, obj=None, **kwargs):
"""Returns a BaseInlineFormSet class for use in admin add/change views."""
if 'fields' in kwargs:
@@ -1543,7 +1547,7 @@ def get_formset(self, request, obj=None, **kwargs):
"exclude": exclude,
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
"extra": self.get_extra(request, obj, **kwargs),
- "max_num": self.max_num,
+ "max_num": self.get_max_num(request, obj, **kwargs),
"can_delete": can_delete,
}
View
26 docs/ref/contrib/admin/index.txt
@@ -1728,6 +1728,11 @@ The ``InlineModelAdmin`` class adds:
doesn't directly correlate to the number of objects, but can if the value
is small enough. See :ref:`model-formsets-max-num` for more information.
+ .. versionadded:: 1.6
+
+ :meth:`InlineModelAdmin.get_max_num` also allows you to customize the
+ maximum number of extra forms.
+
.. attribute:: InlineModelAdmin.raw_id_fields
By default, Django's admin uses a select-box interface (<select>) for
@@ -1787,6 +1792,27 @@ The ``InlineModelAdmin`` class adds:
return extra - obj.binarytree_set.count()
return extra
+.. method:: InlineModelAdmin.get_max_num(self, request, obj=None, **kwargs)
+
+ .. versionadded:: 1.6
+
+ Returns the maximum number of extra inline forms to use. By default,
+ returns the :attr:`InlineModelAdmin.max_num` attribute.
+
+ Override this method to programmatically determine the maximum number of
+ inline forms. For example, this may be based on the model instance
+ (passed as the keyword argument ``obj``)::
+
+ class BinaryTreeAdmin(admin.TabularInline):
+ model = BinaryTree
+
+ def get_max_num(self, request, obj=None, **kwargs):
+ max_num = 10
+ if obj.parent:
+ return max_num - 5
+ return max_num
+
+
Working with a model with two or more foreign keys to the same parent model
---------------------------------------------------------------------------
View
5 docs/releases/1.6.txt
@@ -292,9 +292,10 @@ Minor features
:meth:`~django.db.models.query.QuerySet.select_related` can be cleared using
``select_related(None)``.
-* The :meth:`~django.contrib.admin.InlineModelAdmin.get_extra` method on
+* The :meth:`~django.contrib.admin.InlineModelAdmin.get_extra` and
+ :meth:`~django.contrib.admin.InlineModelAdmin.get_max_num` methods on
:class:`~django.contrib.admin.InlineModelAdmin` may be overridden to
- customize the number of extra inline forms.
+ customize the extra and maximum number of inline forms.
Backwards incompatible changes in 1.6
=====================================
View
9 tests/admin_inlines/admin.py
@@ -129,7 +129,7 @@ class ChildModel1Inline(admin.TabularInline):
class ChildModel2Inline(admin.StackedInline):
model = ChildModel2
-# admin for #19425
+# admin for #19425 and #18388
class BinaryTreeAdmin(admin.TabularInline):
model = BinaryTree
@@ -137,9 +137,14 @@ def get_extra(self, request, obj=None, **kwargs):
extra = 2
if obj:
return extra - obj.binarytree_set.count()
-
return extra
+ def get_max_num(self, request, obj=None, **kwargs):
+ max_num = 3
+ if obj:
+ return max_num - obj.binarytree_set.count()
+ return max_num
+
# admin for #19524
class SightingInline(admin.TabularInline):
model = Sighting
View
6 tests/admin_inlines/tests.py
@@ -197,12 +197,18 @@ def test_custom_get_extra_form(self):
bt_head = BinaryTree.objects.create(name="Tree Head")
bt_child = BinaryTree.objects.create(name="First Child", parent=bt_head)
+ # The maximum number of forms should respect 'get_max_num' on the
+ # ModelAdmin
+ max_forms_input = '<input id="id_binarytree_set-MAX_NUM_FORMS" name="binarytree_set-MAX_NUM_FORMS" type="hidden" value="%d" />'
# The total number of forms will remain the same in either case
total_forms_hidden = '<input id="id_binarytree_set-TOTAL_FORMS" name="binarytree_set-TOTAL_FORMS" type="hidden" value="2" />'
+
response = self.client.get('/admin/admin_inlines/binarytree/add/')
+ self.assertContains(response, max_forms_input % 3)
self.assertContains(response, total_forms_hidden)
response = self.client.get("/admin/admin_inlines/binarytree/%d/" % bt_head.id)
+ self.assertContains(response, max_forms_input % 2)
self.assertContains(response, total_forms_hidden)
Please sign in to comment.
Something went wrong with that request. Please try again.