Django реализует наследование модели с помощью OneToOneField между таблицей родительской модели и таблицей дочерней модели. Когда вы делаете Base.object.all()
, Django запрашивает только базовую таблицу, и поэтому не может узнать, что такое дочерняя таблица. Поэтому, к сожалению, невозможно перейти непосредственно к экземпляру дочерней модели без дополнительных запросов.
Этот фрагмент показывает общий метод добавления поля ContentType к базовой модели:
from django.contrib.contenttypes.models import ContentType
class Base(models.Model):
content_type = models.ForeignKey(ContentType,editable=False,null=True)
def save(self):
if(not self.content_type):
self.content_type = ContentType.objects.get_for_model(self.__class__)
self.save_base()
def as_leaf_class(self):
content_type = self.content_type
model = content_type.model_class()
if(model == Base):
return self
return model.objects.get(id=self.id)
Затем вы можете сказать if Base.content_type.model_class()
, чтобы определить тип.
Здесь - еще один фрагмент кода, который добавляет в микс собственный менеджер.
Как видите, оба эти решения могут быть чрезвычайно дорогими. Если у вас большое количество экземпляров, использование метода as_leaf_class () потребует один запрос для каждого элемента.
Вместо этого, если у вас есть известный набор дочерних моделей, просто запросите каждую модель отдельно и объедините экземпляры в один список.