Я читаю эти вопросы
Динамическое создание запросов фильтра Django с помощью args и kwargs
Я не могу получить то, что делает этот оператор
filter(reduce(operator.or_, argument_list))
или
filter(reduce(operator.and_, query_list))
Я читаю эти вопросы
Динамическое создание запросов фильтра Django с помощью args и kwargs
Я не могу получить то, что делает этот оператор
filter(reduce(operator.or_, argument_list))
или
filter(reduce(operator.and_, query_list))
filter
является регулярным методом диспетчера моделей Django, поэтому ничего не объяснять.
reduce
- встроенная функция, аналогичная приведенному ниже коду:
def reduce(func, items):
result = items.pop()
for item in items:
result = func(result, item)
return result
Где func
- пользовательская функция.
operator.or_
- это стандартная библиотечная функция python, которая обертывает оператор or
. Он похож на этот код:
def or_(a, b):
return a | b
Например:
reduce(operator.or_, [False, False, True])
Вернет True
.
В контексте вашего примера операторы or
и and
перегружены и поэтому должны возвращать новый запрос, объединенный с меньшими частями, все конкатенированные оператором or
или and
.
Документы Python описывают reduce
как:
Применяя функцию двух аргументов кумулятивно к элементам итерации слева направо, чтобы уменьшить итерабельность до единственного значения
Таким образом, это позволяет нам легко и быстро выполнять одну функцию (которая принимает два параметра, то есть добавляет a в b) многократно по набору данных с помощью одного простого вызова функции.
В случае этой проблемы Django мы хотим построить один объект QuerySet
, взяв список объектов индивидуального запроса (Q
) и кумулятивно выполнив операцию AND
или OR
на них, чтобы получить один запрос
Например, для запросов [Q(1), Q(2), Q(3)]
сначала мы хотим OR
Q(1)
с Q(2)
, а затем OR
результат этой операции с Q3
, чтобы дать нам наш окончательный запрос
Мы привыкли видеть операции в python (например, сложение или вычитание), написанные как A + B
(или в случае or'ing: A | B
), но python также предоставляет функции для их выполнения (т.е. or(a, b)
, и and(a, b)
, которые будут делать то же самое). Они полезны в таких ситуациях, поскольку они могут применяться в качестве параметров для других методов. Эти функции, такие как "добавить", "вычесть" и т.д., Находятся в модуле operator
.
Итак, используя модуль operators
, мы видим, что reduce(operator.and_, query_list)
принимает каждый Q
объект в нашем списке и "и" его с текущими результатами предыдущих объектов в списке.