Как запрашивать дочерние модели из данных родительской модели?

В настоящее время у меня есть такой набор моделей:

class BaseModel(models.Model):
    approved = models.BooleanField()

class ModelA(BaseModel):
    # model fields

class ModelB(BaseModel):
    # models fields

class ModelC(BaseModel):
    # model fields

Я хотел бы получить список всех экземпляров ModelA, ModelB и ModelC с approved=True.

Я могу запросить BaseModel с помощью набора queryset:

BaseModel.objects.filter(approved=True)

, но это возвращает все экземпляры BaseModel, а не ModelA, ModelB или ModelC. Я бы хотел, чтобы мой набор запросов содержал экземпляры каждой модели - желательно без исчерпывающего запроса всех возможных дочерних моделей BaseModel.

Есть ли способ сделать это?

Так поступает django-polymorphic [readthedocs.io], но наследование модели часто не хорошая идея: оно будет создавать множество JOIN, делая запрос намного более медленным.

По сути, полиморфный Django будет делать запрос с:

BaseModel.objects.filter(approved=True).select_related(
    'modela', 'modelb', 'modelc'
)

тогда будет показано, с чем JOIN был успешен:

for item in queryset:
    if hasattr(item, 'modela'):
        # use item.modela instead…
        pass
    if hasattr(item, 'modelb'):
        # use item.modelb instead…
        pass
    if hasattr(item, 'modelc'):
        # use item.modelc instead…
        pass

При этом наследование в реляционных базах данных часто не является хорошей идеей и приводит не только к узким местам в производительности, но и к неудобным запросам. Поэтому использовать его в любом случае может быть не очень хорошей идеей. Да, в Django это реализовано, но, вероятно, следует использовать в крайнем случае.

Вернуться на верх