⟵back

Django conditional expression classes

I recently discovered a really cool Django feature — conditional expression classes that can be used in querysets to mimic if/else statements. Here’s an example I’ve adapted from the Django 4.1 documentation:

from django.db.models import When, Q
from my_app.models import Client

"""
We have the model Client, which includes the 
fields `account_type` and `name`. The kwarg
`then` takes one of the fields as a string:
"""

When(account_type=Client.GOLD, then='name')

"""
If the name starts with "John" or "George", then
it evaluates to True, i.e. we only get names that
meet those conditions:
"""

When(
    Q(name__startswith="John") | Q(name__startswith="Paul"),
    then='name'
)

Something quite poetic about it, no?

We can evaluate according to more conditions by adding the the Case() class to it, which can take multiple When() arguments:

from django.db.models import Case, Q, When
from my_app.models import Client


When(account_type=Client.GOLD, then='name')

Case(
    When(
        Q(name__startswith="John") | Q(name__startswith="Paul"),
        then='name'
    ),
    When(
        Q(name__endswith="Lennon") | Q(name__endswith="McCartney"),
        then='name'
    )
)

You can probably guess that we are trying to find all clients whose first name is either John or Paul, and whose last name is either Lennon or McCartney.

In the Django source code, you can see that both Case and When are based on the Expression class and see how they are built; Django, after all, is just a program that we use with our programs. It's pretty cool to have reached a point in my career where I'm curious about what goes on behind the scenes of the code that someone else wrote, rather than merely using it. Extending it, if you will.