Я читаю эти вопросы
Динамическое создание запросов фильтра 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 объект в нашем списке и "и" его с текущими результатами предыдущих объектов в списке.