This builds on top of a fix in Django 1.6, and has a workaround for
Django 1.4 and 1.5. When the base class points to a model that no longer
exists, it will be silently dropped in the polymorphic queryset results.
This behavior is identical to iterating over results when the derived
table doesn't have the object anymore.
As more methods are added to the PolymorphicModel, the attr dict changes
ordering in the meta class. By making the ordering of managers
consistent, this problem no longer occurs.
* The custom manager was not assigned to _default_manager;
get_first_user_defined_manager() always returned None
* The PolymorphicManager couldn't remember it's custom queryset;
a RelatedManager creates a new instance of a manager, so the queryset
parameter should be known at class-level, not object level.
* The old method of providing a custom queryset class has been deprecated.
The reason polymorphic broke was because it couldn't find some managers
anymore in the inheritance tree. Django 1.5 removes these and replaces
them with an `AbstractManagerDescriptor`. This patch restores those objects
As discovered in django-polymorphic-tree and django-fluent-pages,
the raw_id_fields didn't work in Django 1.4 because the fields actively
check which models are actually registered in the admin site.
Hence, the parent admin site _registry is inserted in the child admin as
well. This also completely moves the initialisation of the child admin
into this class, using a `get_child_models()` function,
akin to the static `child_models` attribute.
During the development of django-polymorphic-tree it was discovered that
the PolymorphicParentModelAdmin could actually be made much simpler.
It features a `child_models` attribute now, so there is very little code
needed to actually implement a polymorphic admin now.
Also found various issues which are together fixed in this commit for
pulling.
Extracted from django-fluent-pages, ready for other apps too.
The polymorphic admin is implemented via a parent admin for the base
model, and separate admin interfaces for the child models.
The parent model needs to inherit PolymorphicParentModelAdmin,
and override `get_admin_for_model()` and `get_child_model_classes()`
to find the child admin interfaces.
The derived models have their own `ModelAdmin` class, which inherits
from `PolymorphicChildModelAdmin`. The parent admin redirects it's
change and delete views to the child admin.
By adding `polymorphic` to the INSTALLED_APPS, the breadcrumbs will be
fixed as well, to remain unchanged between the child applications.