I am reading this questions
Constructing Django filter queries dynamically with args and kwargs
I am not able to get what does this operator do
fi
The Python docs describe reduce
as:
Applying a function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value
So it allows us to easily and quickly perform a single function (that takes two parameters, i.e. add a to b) numerous times over a set of data with one simple function call.
In the case of this Django problem, we want to construct a single QuerySet
object by taking a list of individual query (Q
) objects and cumulatively performing an AND
or OR
operation on them to get a single query
For example, for the queries [Q(1), Q(2), Q(3)]
we want to OR
Q(1)
with Q(2)
first, and then OR
the result of that operation with Q3
to give us our final query
We are used to seeing operations in python (such as addition or subtraction) written like A + B
(or in the case of or'ing: A | B
) but python also provides functions to perform these (i.e. or(a, b)
, and and(a, b)
which would do the same thing). These are useful in situations such as these, as they can be applied as parameters to other methods. These functions such as 'add', 'subtract' etc. are in the operator
module.
So using the operators
module, we see that reduce(operator.and_, query_list)
is taking each Q
object in our list, and "and'ing" it with the ongoing results of the previous objects in the list.
filter
is a regular method of Django Model Manager, so there is nothing to explain.
reduce
is a built-in function similar to the code below:
def reduce(func, items):
result = items.pop()
for item in items:
result = func(result, item)
return result
Where func
is a user defined function.
operator.or_
is a python standard library function that wraps the or
operator. It is similar to this code:
def or_(a, b):
return a | b
For example:
reduce(operator.or_, [False, False, True])
Will return True
.
In your example context, the or
and the and
operators are overloaded and therefore it should return a new query combined of smaller parts all concatenated by or
or and
operator.