polymorphic.managers

The manager class for use in the models.

The PolymorphicManager class

class polymorphic.managers.PolymorphicManager

Bases: Manager, Generic[_All, _Base]

Manager for PolymorphicModel

Usually not explicitly needed, except if a custom manager or a custom queryset class is to be used.

queryset_class

alias of PolymorphicQuerySet

create_from_super(obj, **kwargs)

Create an instance of this manager’s model class from the given instance of a parent class.

This is useful when “promoting” an instance down the inheritance chain.

Parameters:
  • obj (Model) – An instance of a parent class of the manager’s model class.

  • kwargs (Any) – Additional fields to set on the new instance.

Returns:

The newly created instance.

Return type:

_Base

get_queryset()

Return a new QuerySet object. Subclasses can override this method to customize the behavior of the Manager.

Return type:

PolymorphicQuerySet

The PolymorphicQuerySet class

class polymorphic.managers.PolymorphicQuerySet

Bases: QuerySet, Generic[_All, _Base]

QuerySet for PolymorphicModel

Contains the core functionality for PolymorphicModel

Usually not explicitly needed, except if a custom queryset class is to be used.

classmethod as_manager()

Override base as_manager() to return a manager extended from polymorphic.managers.PolymorphicManager.

Return type:

Manager

__init__(*args, **kwargs)
Parameters:
Return type:

None

aggregate(*args, **kwargs)

translate the polymorphic field paths in the kwargs, then call vanilla aggregate. We need no polymorphic object retrieval for aggregate => switch it off.

Parameters:
Return type:

dict[str, Any]

annotate(*args, **kwargs)

translate the polymorphic field paths in the kwargs, then call vanilla annotate. _get_real_instances will do the rest of the job after executing the query.

Parameters:
Return type:

Self

bulk_create(objs, batch_size=None, ignore_conflicts=False, update_conflicts=False, update_fields=None, unique_fields=None)

Insert each of the instances into the database. Do not call save() on each of the instances, do not send any pre/post_save signals, and do not set the primary key attribute if it is an autoincrement field (except if features.can_return_rows_from_bulk_insert=True). Multi-table models are not supported.

Parameters:
Return type:

list[_All]

defer(field: None, /) Self
defer(*fields: str) Self

Translate the field paths in the args, then call vanilla defer.

Also retain a copy of the original fields passed, which we’ll need when we’re retrieving the real instance (since we’ll need to translate them again, as the model will have changed).

delete()

Deletion will be done non-polymorphically because Django’s multi-table deletion mechanism is already walking the class hierarchy and producing a correct deletion graph. Introducing polymorphic querysets into the deletion process disrupts the model hierarchy/relationship traversal.

Return type:

tuple[int, dict[str, int]]

get_real_instances(base_result_objects=None)

Cast a list of objects to their actual classes.

This does roughly the same as:

return [ o.get_real_instance() for o in base_result_objects ]

but more efficiently.

Return type:

PolymorphicQuerySet

Parameters:

base_result_objects (Iterable[_All] | None)

instance_of(__a: type[_A], /) PolymorphicQuerySet
instance_of(__a: type[_A], __b: type[_B], /) PolymorphicQuerySet
instance_of(__a: type[_A], __b: type[_B], __c: type[_C], /) PolymorphicQuerySet
instance_of(__a: type[_A], __b: type[_B], __c: type[_C], __d: type[_D], /) PolymorphicQuerySet
instance_of(*args: type['PolymorphicModel']) PolymorphicQuerySet

Filter the queryset to only include the classes in args (and their subclasses).

non_polymorphic()

switch off polymorphic behaviour for this query. When the queryset is evaluated, only objects of the type of the base class used for this query are returned.

Return type:

PolymorphicQuerySet

not_instance_of(*args)

Filter the queryset to exclude the classes in args (and their subclasses).

Parameters:

args (type['PolymorphicModel'])

Return type:

Self

only(*fields)

Translate the field paths in the args, then call vanilla only.

Also retain a copy of the original fields passed, which we’ll need when we’re retrieving the real instance (since we’ll need to translate them again, as the model will have changed).

Parameters:

fields (str)

Return type:

Self

order_by(*field_names)

translate the field paths in the args, then call vanilla order_by.

Parameters:

field_names (str | Combinable)

Return type:

Self

Type Hint Descriptors

polymorphic.managers._All = +_All

This TypeVar represents the union of all possible polymorphic types that a manager may return. All models must derive from PolymorphicModel

polymorphic.managers._Base = +_Base

This TypeVar represents the base model type from which polymorphic models derive. For managers on a PolymorphicModel subclass, you will likely want to use Self.

polymorphic.managers._Through = +_Through

This TypeVar represents the “through” model type for many-to-many relations. By default it is just a regular Model, which will lack the foreign key relations to the linked models.

polymorphic.managers._Nullable = ~_Nullable

Provided for nullable relations - should be set to Literal[True] if the relation is nullable, otherwise can be left as the default Literal[False].

polymorphic.managers.Nullable

A more readable type hint alias to indicate that a relation is nullable.

alias of Literal[True]

class polymorphic.managers.PolymorphicForwardManyToOneDescriptor

Bases: ForwardManyToOneDescriptor, Generic[_All, _Base, _Nullable]

Use this descriptor class as a type hint for your ForeignKey relations to polymorphic models. For example:

Note

Your typing system will likely flag an assignment error on the class attribute - this is unfortunate but unavoidable - we suggest you add a # type: ignore[assignment].

parent: PolymorphicForwardManyToOneDescriptor[
    ParentModel | Child1 | Child2,
    ParentModel,
    Nullable,
] = models.ForeignKey(
    ParentModel,
    on_delete=models.CASCADE,
    null=True,
)
class polymorphic.managers.PolymorphicReverseManyToOneDescriptor

Bases: ReverseManyToOneDescriptor, Generic[_All, _Base]

Use this descriptor class as a type hint for your reverse ForeignKey relations to polymorphic models. For example:

class ParentModel(PolymorphicModel):
    models.ForeignKey(
        RelatedModel,
        on_delete=models.CASCADE,
        null=True,
        related_name="reverse"
    )

class RelatedModel(models.Model):

    reverse: PolymorphicReverseManyToOneDescriptor[
        ParentModel | Child1 | Child2,
        ParentModel
    ]
class polymorphic.managers.PolymorphicForwardOneToOneDescriptor

Bases: ForwardOneToOneDescriptor, PolymorphicForwardManyToOneDescriptor, Generic[_All, _Base, _Nullable]

Use this descriptor class as a type hint for your OneToOneField relations to polymorphic models. For example:

Note

Your typing system will likely flag an assignment error on the class attribute - this is unfortunate but unavoidable - we suggest you add a # type: ignore[assignment].

parent: PolymorphicForwardOneToOneDescriptor[
    ParentModel | Child1 | Child2,
    ParentModel,
    Nullable,
] = models.OneToOneField(
    ParentModel,
    on_delete=models.CASCADE,
    null=True,
)
class polymorphic.managers.PolymorphicReverseOneToOneDescriptor

Bases: ReverseOneToOneDescriptor, Generic[_All, _Base, _Nullable]

Use this descriptor class as a type hint for your reverse OneToOneField relations to polymorphic models. For example:

class ParentModel(PolymorphicModel):
    models.OneToOneField(
        RelatedModel,
        on_delete=models.CASCADE,
        null=True,
        related_name="reverse"
    )

class RelatedModel(models.Model):

    reverse: PolymorphicReverseOneToOneDescriptor[
        ParentModel | Child1 | Child2,
        ParentModel,
        Nullable,
    ]
class polymorphic.managers.PolymorphicManyToManyDescriptor

Bases: ManyToManyDescriptor, Generic[_All, _Base, _Through]

Use this descriptor class as a type hint for your forward and reverse ManyToManyField relations to/from polymorphic models. For example:

to_parents: PolymorphicManyToManyDescriptor[
    ParentModel | Child1 | Child2,  # all possible polymorphic types
    ParentModel,                    # the base type (for non_polymorphic)
    ThroughModel                    # if custom through model
] = models.ManyToManyField(         # type: ignore[assignment]
    "ParentModel",
    related_name="to_parents_reverse"
)