# Imports
from django.db import models
from superdjango.exceptions import DeeplyDisturbingError
# Exports
__all__ = (
"PolymorphicMixin",
)
# Models
[docs]class PolymorphicMixin(models.Model):
"""A mixin for models that extend a polymorphic model.
The purpose of which is to provide a means of acquiring the pointer field that refers back to the parent model.
"""
class Meta:
abstract = True
[docs] @classmethod
def get_pointer_field(cls):
"""Get the field instance for the pointer field.
:raise: DeeplyDisturbingError
.. warning::
The first non-abstract parent is used for identifying the pointer field. If you encounter issues with this,
override the method and return the correct field.
"""
for parent in cls.mro():
if parent.__name__ == cls.__name__:
continue
_parent = parent()
# noinspection PyProtectedMember
if not _parent._meta.abstract:
field_name = "%s_ptr" % parent.__name__.lower()
# noinspection PyUnresolvedReferences
return cls._meta.get_field(field_name)
raise DeeplyDisturbingError("Model does not extend another concrete model: %s" % cls.__name__)
[docs] @staticmethod
def is_polymorphic_model():
"""Indicates the model implements polymorphic behavior.
:rtype: bool
"""
return True