Expression Comparison with Combinable

TL;DR: Allow us to do

queryset.annotate({
   "is_happy": F("expectations") > F("reality")
})

…and the rest of comparison operators (<, <=, >=, ==).


The Combinable class

Provide[s] the ability to combine one or two objects with some connector. For example F(‘foo’) + F(‘bar’).

However, it currently only allows arithmetic operators( + - * / ^ %) and bitwise operators (& | << >> #). Some people have expressed the desire to allow boolean comparison in here. There are workarounds to this, but they’re not neat (a. using ExpressionWrapper, b. using Case and When).

There is a small disadvantage that we have to declare the output field as a BooleanField, but we can include that in the code.

The code would look something like this:

class Combinable:
    ...
    GT = '>'

    def _bool_combine(self, other, connector):
        return ExpressionWrapper(
            self._combine(other, connector, False),
            output_field=models.BooleanField(),
        )

    def __gt__(self, other):
        return self._bool_combine(other, self.GT)