Fix get parent admin when intermediate not root ctype model is registered
This change fixes an issue where django-polymorphic raises a `ParentAdminNotRegistered` exception when you register an admin for a child model ancestor, but not for the root ancestor as pointed to by the `polymorphic_ctype` field. This error occurs only when you *Save* the child model detail form, not when you *Save and continue* on that same form. This situation occurs for us when using django-fluent-pages version 1.0.1 which has an intermediate `Page` model registered with a parent admin to show the pages listing. The existing `_get_parent_admin` method expects an admin to be registered for the root `UrlNode` model pointed to by the `polymorphic_ctype` field. This fix uses a potentially naive and slow brute-force approach where it walks up the class hierarchy and checks whether a parent admin is registered for each ancestor model, unless/until it finds one. See also https://github.com/ic-labs/django-icekit/issues/31/fix_request_path_info
parent
db6d7ed213
commit
37f92b3a3f
|
|
@ -1,12 +1,15 @@
|
||||||
"""
|
"""
|
||||||
The child admin displays the change/delete view of the subclass model.
|
The child admin displays the change/delete view of the subclass model.
|
||||||
"""
|
"""
|
||||||
|
import inspect
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.core.urlresolvers import resolve
|
from django.core.urlresolvers import resolve
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .helpers import PolymorphicInlineSupportMixin
|
from .helpers import PolymorphicInlineSupportMixin
|
||||||
|
from ..admin import PolymorphicParentModelAdmin
|
||||||
|
|
||||||
|
|
||||||
class ParentAdminNotRegistered(RuntimeError):
|
class ParentAdminNotRegistered(RuntimeError):
|
||||||
|
|
@ -123,6 +126,21 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
||||||
try:
|
try:
|
||||||
return self.admin_site._registry[parent_model]
|
return self.admin_site._registry[parent_model]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
# Admin is not registered for polymorphic_ctype model, but it may
|
||||||
|
# be registered for a model in the class ancestry between this
|
||||||
|
# model and the root parent one.
|
||||||
|
for klass in inspect.getmro(self.model):
|
||||||
|
# Ignore model ancestors that are not also subclasses of the
|
||||||
|
# target ctype model
|
||||||
|
if not issubclass(klass, parent_model):
|
||||||
|
continue
|
||||||
|
# Fetch admin instance for model class (may return None)
|
||||||
|
model_admin = self.admin_site._registry.get(klass)
|
||||||
|
# Ignore admin (or None) that isn't a polymorphic parent admin
|
||||||
|
if not isinstance(model_admin, PolymorphicParentModelAdmin):
|
||||||
|
continue
|
||||||
|
return model_admin # Success!
|
||||||
|
# If we get this far without returning there is no admin available
|
||||||
raise ParentAdminNotRegistered("No parent admin was registered for a '{0}' model.".format(parent_model))
|
raise ParentAdminNotRegistered("No parent admin was registered for a '{0}' model.".format(parent_model))
|
||||||
|
|
||||||
def response_post_save_add(self, request, obj):
|
def response_post_save_add(self, request, obj):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue