Filter django QuerySet on subclassed type (multi-table inheritance)?

Viewed 102

I'm looking for an efficient model manager method that uses the following class structure to generate a QuerySet, as described below:

#models.py
from django.db import models

class SuperModel(models.Model):
    date_of_interest = models.DateField(...)
    # <other model_fields>

class SubA(SuperModel):
    # <other model_fields>

class SubB(SuperModel):
    # <other model_fields>

class SubC(SuperModel):
    # <other model_fields>

#somewhere else (eg. views.py)
...    
query_set = SuperModel.objects.filter(date_of_interest=today)
qs_to_list = [e for e in query_set if hasattr(e, 'subb') or hasattr(e, 'subc')]

I would like to keep qs_to_list a QuerySet, so I'm searching for a way to filter with a model manager method, based on the type of subclass. As noted, I'm using multitable inheritance with abstract=False and implicitly using the OneToOneField created with this type of inheritance.

Thanks!

1 Answers

You can filter with:

from django.db.models import Q

SuperModel.objects.filter(
    Q(subb__isnull=False) | Q(subc__isnull=False),
    date_of_interest=today
).distinct()

This will thus make LEFT OUTER JOINs on the SubB and SubC model, and if there is a record with this JOINing for which the SubB and/or SubC is not NULL, we know that it is of type SubB or SubC.

Related