Add a get_child_inlines() hook to inline admin classes

Co-authored-by: Jesús Leganés-Combarro 'piranna <piranna@gmail.com>
Co-authored-by: Brian Kohan <bckohan@gmail.com>
This commit is contained in:
Jesús Leganés-Combarro 'piranna 2024-02-16 07:28:26 +01:00 committed by Brian Kohan
parent 94267f3492
commit 79cd97c47a
No known key found for this signature in database
GPG Key ID: 5C6CE8BA38C43FC1
9 changed files with 44 additions and 15 deletions

1
.gitignore vendored
View File

@ -221,3 +221,4 @@ __marimo__/
test1.db
test2.db
example/example.db

View File

@ -36,6 +36,7 @@
* Jacob Rief
* James Murty
* Jedediah Smith (proxy models support)
* Jesús Leganés-Combarro (Auto-discover child models and inlines, #582)
* John Furr
* Jonas Haag
* Jonas Obrist

View File

@ -4,6 +4,7 @@ Changelog
v4.3.0 (202X-XX-XX)
-------------------
* Implemented `Include get_child_inlines() hook in stacked inline admin forms. <https://github.com/jazzband/django-polymorphic/pull/681>`_
* Fixed `"multi-database support in inheritance accessors. <https://github.com/jazzband/django-polymorphic/pull/550>`_
* Fixed `Caching in inheritance accessor functions <https://github.com/jazzband/django-polymorphic/pull/510>`_
* Fixed `Foreign key resolves to parent class when using abstract models <https://github.com/jazzband/django-polymorphic/issues/437>`_

View File

@ -15,7 +15,7 @@ manage *COMMAND:
import sys
from django.core import management
sys.path.append(os.getcwd())
os.environ["DJANGO_SETTINGS_MODULE"] = "polymorphic.tests.settings"
os.environ["DJANGO_SETTINGS_MODULE"] = "polymorphic.tests.debug"
os.environ["SQLITE_DATABASES"] = "test1.db,test2.db"
management.execute_from_command_line(sys.argv + "{{ COMMAND }}".split(" "))

View File

@ -77,12 +77,22 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
for child_inline in self.child_inline_instances:
self._child_inlines_lookup[child_inline.model] = child_inline
def get_child_inlines(self):
"""
Return the derived inline classes which this admin should handle.
This should return an iterable of
:class:`~polymorphic.admin.inlines.PolymorphicInlineModelAdmin.Child classes,
to override :attr:`child_inlines.
"""
return self.child_inlines or []
def get_child_inline_instances(self):
"""
:rtype List[PolymorphicInlineModelAdmin.Child]
"""
instances = []
for ChildInlineType in self.child_inlines:
for ChildInlineType in self.get_child_inlines():
instances.append(ChildInlineType(parent_inline=self))
return instances

View File

@ -1,3 +1,4 @@
from inspect import isclass
from django.contrib.admin import register, ModelAdmin, site as admin_site
from polymorphic.admin import (
StackedPolymorphicInline,
@ -35,20 +36,25 @@ class PlainAAdmin(ModelAdmin):
search_fields = ["field1"]
class InlineModelAChild(StackedPolymorphicInline.Child):
model = InlineModelA
class InlineModelBChild(StackedPolymorphicInline.Child):
model = InlineModelB
autocomplete_fields = ["plain_a"]
class Inline(StackedPolymorphicInline):
model = InlineModelA
child_inlines = (InlineModelAChild, InlineModelBChild)
def get_child_inlines(self):
return [
child
for child in self.__class__.__dict__.values()
if isclass(child) and issubclass(child, StackedPolymorphicInline.Child)
]
class InlineModelAChild(StackedPolymorphicInline.Child):
model = InlineModelA
class InlineModelBChild(StackedPolymorphicInline.Child):
model = InlineModelB
autocomplete_fields = ["plain_a"]
@register(InlineParent)
class InlineParentAdmin(PolymorphicInlineSupportMixin, ModelAdmin):
inlines = (Inline,)
extra = 1

View File

@ -0,0 +1,3 @@
from .settings import *
DEBUG = True

View File

@ -101,6 +101,7 @@ INSTALLED_APPS = (
"polymorphic",
"polymorphic.tests",
)
MIDDLEWARE = (
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",

View File

@ -93,6 +93,15 @@ class PolymorphicAdminTests(AdminTestCase):
self.admin_post_delete(Model2A, d_obj.pk)
pytest.raises(Model2A.DoesNotExist, (lambda: d_obj.refresh_from_db()))
def test_get_child_inlines(self):
from .admin import Inline
inline = Inline(parent_model=InlineParent, admin_site=admin.site)
child_inlines = inline.get_child_inlines()
self.assertEqual(len(child_inlines), 2)
self.assertEqual(child_inlines[0], Inline.InlineModelAChild)
self.assertEqual(child_inlines[1], Inline.InlineModelBChild)
def test_admin_inlines(self):
"""
Test the registration of inline models.
@ -205,9 +214,6 @@ class _GenericAdminFormTest(StaticLiveServerTestCase):
def setUp(self):
"""Create an admin user before running tests."""
self.admin_username = "admin"
self.admin_password = "password"
self.page = self.browser.new_page()
# Log in to the Django admin
self.page.goto(f"{self.live_server_url}/admin/login/")