How to query child models from parent model data?

I currently have a set of models like so:

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

class ModelA(BaseModel):
    # model fields

class ModelB(BaseModel):
    # models fields

class ModelC(BaseModel):
    # model fields

What I'd like to do is get a list of all instances of ModelA, ModelB, and ModelC with approved=True.

I can query BaseModel with a queryset:

BaseModel.objects.filter(approved=True)

but this returns all instances of BaseModel, not ModelA, ModelB, or ModelC. I'd like my queryset to contain instances of each model -- preferably without exhaustively querying every single possible child model of BaseModel.

Is there a way to do this?

This is what django-polymorphic [readthedocs.io] does, but model inheritance often is not a good idea: it will make a lot of JOINs making the query a lot more slow.

Essentially what Django polymorphic will do is query with:

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

then it will look what JOIN was successful with:

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

That being said, inheritance in relational databases is often not a good idea, and results in performance bottlenecks, but also in inconvenient querying. Therefore it might not be a good idea to use it anyway. Yes, Django implemented that, but probabably should be used as last resort.

Back to Top