diff --git a/src/polymorphic/admin/childadmin.py b/src/polymorphic/admin/childadmin.py index 042c534b..731acc10 100644 --- a/src/polymorphic/admin/childadmin.py +++ b/src/polymorphic/admin/childadmin.py @@ -160,26 +160,22 @@ def _get_parent_admin(self): # when parent_model is in among child_models, just return super instance return super() - try: - return self.admin_site._registry[parent_model] - except KeyError: - # Admin is not registered for polymorphic_ctype model, but perhaps it's registered - # for a intermediate proxy model, between the parent_model and this model. - for klass in inspect.getmro(self.model): - if not issubclass(klass, parent_model): - continue # e.g. found a mixin. - - # Fetch admin instance for model class, see if it's a possible candidate. - model_admin = self.admin_site._registry.get(klass) - if model_admin is not None and isinstance( - model_admin, PolymorphicParentModelAdmin - ): - return model_admin # Success! - - # If we get this far without returning there is no admin available - raise ParentAdminNotRegistered( - f"No parent admin was registered for a '{parent_model}' model." - ) + # Only PolymorphicParentModelAdmin registrations are considered, whether + # they are for the polymorphic root model or an intermediate proxy/model + # between the parent_model and this model. + for klass in inspect.getmro(self.model): + if not issubclass(klass, parent_model): + continue # e.g. found a mixin. + + # Fetch admin instance for model class, see if it's a possible candidate. + model_admin = self.admin_site._registry.get(klass) + if model_admin is not None and isinstance(model_admin, PolymorphicParentModelAdmin): + return model_admin # Success! + + # If we get this far without returning there is no admin available + raise ParentAdminNotRegistered( + f"No parent admin was registered for a '{parent_model}' model." + ) def response_post_save_add(self, request, obj): return self._get_parent_admin().response_post_save_add(request, obj) diff --git a/src/polymorphic/tests/test_admin.py b/src/polymorphic/tests/test_admin.py index c5011085..a7c6da9e 100644 --- a/src/polymorphic/tests/test_admin.py +++ b/src/polymorphic/tests/test_admin.py @@ -1629,6 +1629,28 @@ class Model2CAdmin(PolymorphicChildModelAdmin): parent = c_admin._get_parent_admin() assert isinstance(parent, PolymorphicParentModelAdmin) + def test_child_admin_get_parent_admin_skips_regular_root_admin(self): + """_get_parent_admin() ignores a registered root ModelAdmin when finding the polymorphic parent.""" + + @self.register(Model2A) + class Model2ARootAdmin(admin.ModelAdmin): + pass + + @self.register(Model2B) + class Model2BParentAdmin(PolymorphicParentModelAdmin): + base_model = Model2B + child_models = (Model2C,) + + @self.register(Model2C) + class Model2CAdmin(PolymorphicChildModelAdmin): + base_model = Model2B + + c_admin = self.get_admin_instance(Model2C) + parent = c_admin._get_parent_admin() + + assert parent is self.get_admin_instance(Model2B) + assert parent is not self.get_admin_instance(Model2A) + def test_child_admin_get_parent_admin_not_registered(self): """_get_parent_admin() raises ParentAdminNotRegistered when MRO has no parent admin.""" from polymorphic.admin.childadmin import ParentAdminNotRegistered