Fixed #27755 -- Added ModelAdmin.get_inlines() hook.
This commit is contained in:
parent
7d49ad7656
commit
917fd9d03f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue