I have a interesting Django problem.
Consider the following:
Model.objects.filter(Q(id=\'test1\') and Q(id=\'test2\'))
this returns the
according to the following tutorial
& is a Binary AND Operator copies a bit to the result if it exists in both operands.
Example: Assume if a = 60; and b = 13; Now in binary format they will be as follows:
a = 0011 1100
b = 0000 1101
(a & b) will give 12 which is 0000 1100
and Called Logical AND operator. If both the operands are true then then condition becomes true.
Example: (a and b) is true.
So the & was performing binary addition on your query set. Interesting.
I think you want OR
here, and not AND
filters = ['test1', 'test2', 'test3', 'test4']
filtered = Model.objects.filter(Q(id = filters[0]))
for f in filters[1:]:
subset = Model.objects.filter(Q(id = f))
filtered = filtered | subset
If you want Django ORM to return test1 and test2, you should use :
Model.objects.filter(Q(id='test1') | Q(id='test2'))
Model.objects.filter(Q(id='test1') & Q(id='test2'))
means return model objects whose id is test1 while its is test2 at the same time. Of course, django will return an empty QuerySet.
and is a boolean operator in Python. For operation x and y
the result is if x is false, then x, else y
. Thus Q(id='test1') and Q(id='test2')
equals Q(id='test1')
, it is not what you want.
&/| is the the bitwise and/or operator.
BTW, there's no way to override the boolean operator, but you can override &/|
operators in your class by define a method named __and__
/ __or__
.
below is the source code of the django Q object[github]:
class Q(tree.Node):
"""
Encapsulates filters as objects that can then be combined logically (using
& and |).
"""
# Connection types
AND = 'AND'
OR = 'OR'
default = AND
def __or__(self, other):
return self._combine(other, self.OR)
def __and__(self, other):
return self._combine(other, self.AND)
...