polymorphic.utils

class polymorphic.utils.ParentLinkInfo

Bases: object

Information about a parent table link in a polymorphic model.

__init__(model, link)
Parameters:
Return type:

None

polymorphic.utils.concrete_descendants(model_class, include_proxy=False)

Get a list of all concrete (non-abstract, non-proxy) descendant model classes in tree order with leaf descendants last. Results are cached.

polymorphic.utils.get_base_polymorphic_model(ChildModel, allow_abstract=False)

First the first concrete model in the inheritance chain that inherited from the PolymorphicModel.

polymorphic.utils.prepare_for_copy(obj)

Prepare a model instance for copying by resetting all primary keys and parent table pointers in the inheritance chain. Copy semantics are application specific. This function only resets the fields required to create a new instance when saved, it does not deep copy related objects or save the new instance (See copying discussion in the Django documentation.):

from polymorphic.utils import prepare_for_copy

original = YourModel.objects.get(pk=1)
prepare_for_copy(original)
# update any related fields here as needed
original.save()  # creates a new object in the database

Tip

Preparation is at the inheritance level of the passed in model. This means you can copy and upcast at the same time. Suppose you have A->B->C inheritance chain, and you have an instance of C that you want to copy as a B instance:

c = C.objects.create()
c_as_b = B.objects.non_polymorphic().get(pk=c.pk)

# copy c as a b instance
prepare_for_copy(c_as_b)
c_as_b.save()

assert B.objects.count() == 2
assert C.objects.count() == 1

If you want polymorphic copying instead:

prepare_for_copy(b_instance.get_real_instance())

This function also works for non-polymorphic multi-table models.

Parameters:

obj – The model instance to prepare for copying.

polymorphic.utils.reset_polymorphic_ctype(*models, **filters)

Set the polymorphic content-type ID field to the proper model Sort the *models from base class to descending class, to make sure the content types are properly assigned.

Add ignore_existing=True to skip models which already have a polymorphic content type.

polymorphic.utils.route_to_ancestor(model_class, ancestor_model)

Returns the first (highest mro precedence - depth first on parents) model inheritance route to the given ancestor model - or an empty list if no such route exists. Results are cached

Warning

This only works for concrete ancestors!

Returns a list of ParentLinkInfo

polymorphic.utils.sort_by_subclass(*classes)

Sort a series of models by their inheritance order.