Fork me on GitHub

One sometimes does not want to filter on a condition, but use a condition as a Boolean field.

What problems are solved with this?

One can use Q objects to filter a condition. But sometimes you also want to use it in an annotation. For example to add an extra attribute to the model objects, or to order for example.

What does this pattern look like?

One can wrap the Q object in a ExpressionWrapper and specify the BooleanField as output_field=…, for example:

from django.db.models import BooleanField, ExpressionWrapper, Q

MyModel.objects.annotate(
    my_condition=ExpressionWrapper(
        Q(pk__lt=14),
        output_field=BooleanField()
    )
)

Extra tips

One can encapsulate the logic with an expression that looks like:

from django.db.models import BooleanField, ExpressionWrapper, Q

def Condition(*args, **kwargs):
    return ExpressionWrapper(Q(*args, **kwargs), output_field=BooleanField())

then one can annotate the condition with:

MyModel.objects.annotate(
    my_condition=Condition(pk__lt=14)
)

the positional and named parameters can be used like one does in a .filter(…) [Django-doc] method call.