mirror of https://github.com/django/django.git
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.
This commit is contained in:
parent
07a73a2714
commit
61524b09cf
|
@ -1516,6 +1516,10 @@ class InlineModelAdmin(BaseModelAdmin):
|
||||||
"""Hook for customizing the number of extra inline forms."""
|
"""Hook for customizing the number of extra inline forms."""
|
||||||
return self.extra
|
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):
|
def get_formset(self, request, obj=None, **kwargs):
|
||||||
"""Returns a BaseInlineFormSet class for use in admin add/change views."""
|
"""Returns a BaseInlineFormSet class for use in admin add/change views."""
|
||||||
if 'fields' in kwargs:
|
if 'fields' in kwargs:
|
||||||
|
@ -1543,7 +1547,7 @@ class InlineModelAdmin(BaseModelAdmin):
|
||||||
"exclude": exclude,
|
"exclude": exclude,
|
||||||
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
||||||
"extra": self.get_extra(request, obj, **kwargs),
|
"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,
|
"can_delete": can_delete,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1728,6 +1728,11 @@ The ``InlineModelAdmin`` class adds:
|
||||||
doesn't directly correlate to the number of objects, but can if the value
|
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.
|
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
|
.. attribute:: InlineModelAdmin.raw_id_fields
|
||||||
|
|
||||||
By default, Django's admin uses a select-box interface (<select>) for
|
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 - obj.binarytree_set.count()
|
||||||
return extra
|
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
|
Working with a model with two or more foreign keys to the same parent model
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -292,9 +292,10 @@ Minor features
|
||||||
:meth:`~django.db.models.query.QuerySet.select_related` can be cleared using
|
:meth:`~django.db.models.query.QuerySet.select_related` can be cleared using
|
||||||
``select_related(None)``.
|
``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
|
: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
|
Backwards incompatible changes in 1.6
|
||||||
=====================================
|
=====================================
|
||||||
|
|
|
@ -129,7 +129,7 @@ class ChildModel1Inline(admin.TabularInline):
|
||||||
class ChildModel2Inline(admin.StackedInline):
|
class ChildModel2Inline(admin.StackedInline):
|
||||||
model = ChildModel2
|
model = ChildModel2
|
||||||
|
|
||||||
# admin for #19425
|
# admin for #19425 and #18388
|
||||||
class BinaryTreeAdmin(admin.TabularInline):
|
class BinaryTreeAdmin(admin.TabularInline):
|
||||||
model = BinaryTree
|
model = BinaryTree
|
||||||
|
|
||||||
|
@ -137,9 +137,14 @@ class BinaryTreeAdmin(admin.TabularInline):
|
||||||
extra = 2
|
extra = 2
|
||||||
if obj:
|
if obj:
|
||||||
return extra - obj.binarytree_set.count()
|
return extra - obj.binarytree_set.count()
|
||||||
|
|
||||||
return extra
|
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
|
# admin for #19524
|
||||||
class SightingInline(admin.TabularInline):
|
class SightingInline(admin.TabularInline):
|
||||||
model = Sighting
|
model = Sighting
|
||||||
|
|
|
@ -197,12 +197,18 @@ class TestInline(TestCase):
|
||||||
bt_head = BinaryTree.objects.create(name="Tree Head")
|
bt_head = BinaryTree.objects.create(name="Tree Head")
|
||||||
bt_child = BinaryTree.objects.create(name="First Child", parent=bt_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
|
# 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" />'
|
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/')
|
response = self.client.get('/admin/admin_inlines/binarytree/add/')
|
||||||
|
self.assertContains(response, max_forms_input % 3)
|
||||||
self.assertContains(response, total_forms_hidden)
|
self.assertContains(response, total_forms_hidden)
|
||||||
|
|
||||||
response = self.client.get("/admin/admin_inlines/binarytree/%d/" % bt_head.id)
|
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)
|
self.assertContains(response, total_forms_hidden)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue