Fixed #27755 -- Added ModelAdmin.get_inlines() hook.

This commit is contained in:
Hasan Ramezani 2019-03-19 16:13:26 +01:00 committed by Mariusz Felisiak
parent 7d49ad7656
commit 917fd9d03f
No known key found for this signature in database
GPG Key ID: 2EF56372BA48CD1B
4 changed files with 45 additions and 1 deletions

View File

@ -327,6 +327,10 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
return self.fieldsets
return [(None, {'fields': self.get_fields(request, obj)})]
def get_inlines(self, request, obj):
"""Hook for specifying custom inlines."""
return self.inlines
def get_ordering(self, request):
"""
Hook for specifying field ordering.
@ -582,7 +586,7 @@ class ModelAdmin(BaseModelAdmin):
def get_inline_instances(self, request, obj=None):
inline_instances = []
for inline_class in self.inlines:
for inline_class in self.get_inlines(request, obj):
inline = inline_class(self.model, self.admin_site)
if request:
if not (inline.has_view_or_change_permission(request, obj) or

View File

@ -1627,6 +1627,16 @@ templates used by the :class:`ModelAdmin` views:
instances of the classes defined in :attr:`inlines` or you might encounter
a "Bad Request" error when adding related objects.
.. method:: ModelAdmin.get_inlines(request, obj)
.. versionadded:: 3.0
The ``get_inlines`` method is given the ``HttpRequest`` and the
``obj`` being edited (or ``None`` on an add form) and is expected to return
an iterable of inlines. You can override this method to dynamically add
inlines based on the request or model instance instead of specifying them
in :attr:`ModelAdmin.inlines`.
.. method:: ModelAdmin.get_urls()
The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for

View File

@ -47,6 +47,10 @@ Minor features
* Added support for the ``admin_order_field`` attribute on properties in
:attr:`.ModelAdmin.list_display`.
* The new :meth:`ModelAdmin.get_inlines()
<django.contrib.admin.ModelAdmin.get_inlines>` method allows specifying the
inlines based on the request or model instance.
:mod:`django.contrib.admindocs`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -429,3 +429,29 @@ class GenericInlineModelAdminTest(SimpleTestCase):
inlines = ma.get_inline_instances(request)
for (formset, inline), other_inline in zip(ma.get_formsets_with_inlines(request), inlines):
self.assertIsInstance(formset, other_inline.get_formset(request).__class__)
def test_get_inline_instances_override_get_inlines(self):
class MediaInline(GenericTabularInline):
model = Media
class AlternateInline(GenericTabularInline):
model = Media
class EpisodeAdmin(admin.ModelAdmin):
inlines = (AlternateInline, MediaInline)
def get_inlines(self, request, obj):
if hasattr(request, 'name'):
if request.name == 'alternate':
return self.inlines[:1]
elif request.name == 'media':
return self.inlines[1:2]
return []
ma = EpisodeAdmin(Episode, self.site)
self.assertEqual(ma.get_inlines(request, None), [])
self.assertEqual(ma.get_inline_instances(request), [])
for name, inline_class in (('alternate', AlternateInline), ('media', MediaInline)):
request.name = name
self.assertEqual(ma.get_inlines(request, None), (inline_class,)),
self.assertEqual(type(ma.get_inline_instances(request)[0]), inline_class)