-
-
Notifications
You must be signed in to change notification settings - Fork 300
Description
Hey !
It seems PolymorphicChildModelAdmin's logic to pick where to redirect after saving a form has a flaw.
In my case, the root model is registeredto the admin (as a regular ModelAdmin, not a PolymorphicParentModelAdmin) only because I need it for autocomplete. I do have an actual PolymorphicParentModelAdmin that represents the parent I want to see in the admin which is for a subclass (so not the root).
As far as I understand, the issue is in PolymorphicChildModelAdmin._get_parent_admin, where before trying to move up the MRO to find the first PolymorphicParentModelAdmin, it checks if the root model is registered in the admin, and if so, returns the root model admin early.
I think we can fix this by removing self.admin_site._registry[parent_model] below (and the try...except around it).
What do you think ? Would that be reasonably backwards compatible ?
Happy to open a pull request but since it's my first contribution here I prefer to ask before putting work in this.
Cheers
class PolymorphicChildModelAdmin(_ModelAdminBase, Generic[_ModelT]):
def _get_parent_admin(self):
# this returns parent admin instance on which to call response_post_save methods
parent_model = self.model._meta.get_field("polymorphic_ctype").model
if parent_model == self.model:
# when parent_model is in among child_models, just return super instance
return super()
try:
return self.admin_site._registry[parent_model] # π΄π΄π΄ DELETE THIS LINE π΄π΄π΄
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."
)