Django Filter Base Class by Child Class Names
django, django-models, python
Solution
It certainly is possible to do this in a single query!
It all comes from the way Django builds up fields to refer to the relationships between the parent and child models. Each child has a `parent-ref` of some sort, which has a `related_name`. You can query on these.
You'll probably find it easiest to start up a `./manage.py shell`, and import your parent model class, and then perform a nonsense query:
Parent.objects.filter(foo='bar')
This should show you the available fields for querying: you can then work out how to build the query:
Parent.objects.filter(is_active=True).filter(
models.Q(a__isnull=False) |
models.Q(b__isnull=False)
).select_subclasses()
This will perform a single query that will fetch all objects of A, all objects of B, that have `is_active` set to `True`, and downcast them.
The thing it is worth pointing out is that `.select_subclasses()` is unable to detect which models are going to be included, so it joins in all subclasses.
However... you can pass values to `select_subclasses` so it only joins (and downcasts) to those subclasses:
Parent.objects.filter(is_active=True).filter(
models.Q(a__isnull=False) |
models.Q(b__isnull=False)
).select_subclasses('a', 'b')
Now, we are no longer joining to tables "c" through "z"!
Problem
I have the following model inheritance structure in Django: ``` class Parent(models.Model): # stuff class A(Parent): # stuff class B(Parent): # stuff class C(Parent): # stuff and the list goes on. ``` I am using InheritanceManager of django-model-utils to filter objects like: ``` Parent.objects.filter(foo=bar).select_subclasses() ``` This works well when I want to filter all subclasses. What I want to do is to filter A and B objects, but not C objects. I want to do this with a single query like ``` Parent.objects.filter(foo=bar, __class__.__name__=A, __class__.__name__=B).select_subclasses() ``` Is it possible to do such a filtering operation, and if possible how?