In Django ORM, how does one go about creating a Q object that is always False?
This is similar to the question about always True Q objects, but the other way round.
Note that this doesn't work:
Foobar.objects.filter(~Q()) # returns a queryset which gives all objects
Why do I want a Q object instead of the simple False value? So that I can combine it with other Q values, like this for example:
condition = always_true_q_object
if something_or_other:
condition = condition | foobar_that_returns_a_q_object()
if something_or_other2:
condition = condition | foobar_that_returns_a_q_object2()
Note: Sam's answer is better. I've left this answer here instead of deleting it so that you can see the 'more hacky' answer that Sam is referring to
What about:
Q(pk__isnull=True)
or
Q(pk=None)
It seems hacky, but it appears to work. For example:
>>> FooBar.objects.filter(Q(x=10)|Q(pk__isnull=True))
[<FooBar: FooBar object>, ...]
>>> FooBar.objects.filter(Q(x=10)&Q(pk__isnull=True))
[]
However, note that it doesn't work as you might expect when OR'd with an empty Q()
.
>>> FooBar.objects.filter(Q()|Q(pk__isnull=True))
[]
The solution to this might be to use Q(pk__isnull=False)
as the 'always True Q'.
>>> FooBar.objects.filter(Q(pk__isnull=False)|Q(pk__isnull=True))
[<FooBar: FooBar object>, ...]
>>> FooBar.objects.filter(Q(pk__isnull=False)&Q(pk__isnull=True))
[]
Using Q(pk__in=[])
seems to be a good way to represent this idiom.
As indicated by @fwip and comments below: Django's ORM nicely recognises this case, knowing this always evaluates to FALSE
. For example:
FooBar.objects.filter(Q(pk__in=[]))
correctly returns an empty QuerySet
without involving any round trip to the database. While:
FooBar.objects.filter(
(Q(pk__in=[]) & Q(foo="bar")) |
Q(hello="world")
)
is optimised down to:
FooBar.objects.filter(
Q(hello="world")
)
i.e. it recognises that Q(pk__in=[])
is always FALSE
, hence the AND
condition can never be TRUE
, so is removed.
To see what queries are actually sent to the database, see: How can I see the raw SQL queries Django is running?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With