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.

Parameters:
Return type:

list[type[Model]]

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

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

Parameters:
Return type:

type[Model] | None

polymorphic.utils.lazy_ctype(model, using='default')

Return the content type id for the given model class if it is in the cache, otherwise return a subquery that can be used to match the content type as part of a larger query. Safe to call before apps are fully loaded.

Parameters:
  • model (type[Model]) – The model class to get the content type for.

  • using (str)

Returns:

The content type for the model class.

Return type:

ContentType object or Subquery

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 (Model) – The model instance to prepare for copying.

Return type:

None

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.

Parameters:
Return type:

None

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

Parameters:
Return type:

list[ParentLinkInfo]

polymorphic.utils.sort_by_subclass(*classes)

Sort a series of models by their inheritance order.

Parameters:

classes (type[Model])

Return type:

list[type[Model]]