В примере вы можете увидеть фильтр запросов с множественным ИЛИ:
Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Например, это приводит к:
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
Однако я хочу создать этот фильтр запроса из списка. Как это сделать?
например [1, 2, 3] -> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Article.objects.filter(pk__in=[1, 2, 3])
в современном django, но вопрос все еще актуален, если вы хотите сделать что-то более продвинутое, объединяя объекты Q вместе с помощью OR.Ответы:
Вы можете связать свои запросы следующим образом:
источник
Для построения более сложных запросов также есть возможность использовать встроенные в объект Q () константы Q.OR и Q.AND вместе с методом add () следующим образом:
источник
q_objects |= Q(pk=item)
list
окажется пустым, вы вернете эквивалентArticle.objects.all()
. Однако легко смягчить ситуацию, вернувшисьArticle.objects.none()
для этого теста.q_objects
сQ(id__in=[])
. Он всегда будет терпеть неудачу, если не будет выполнено ИЛИ с чем-либо, и оптимизатор запросов с этим справится.Более короткий способ написать ответ Дэйва Уэбба с использованием функции сокращения Python :
источник
functools.reduce
. источникoperator.or_
вместо лямбды.источник
operator
?Возможно, лучше использовать оператор sql IN.
См. Справку по API queryset .
Если вам действительно нужно делать запросы с динамической логикой, вы можете сделать что-то вроде этого (некрасиво + не проверено):
источник
query |= Q(field=cond)
См. Документы :
Обратите внимание, что этот метод работает только для поиска по первичному ключу, но, похоже, это именно то, что вы пытаетесь сделать.
Итак, что вы хотите:
источник
В случае, если мы хотим программно установить, какое поле db мы хотим запрашивать:
источник
Решение , которое используют
reduce
иor_
операторы для фильтра, многократно полей.ps
f
- это новый строковый литерал формата. Он был представлен в Python 3.6.источник
Вы можете использовать оператор | = для программного обновления запроса с помощью объектов Q.
источник
Это для динамического списка пакетов:
источник
q = Q()
вместоq = None
, а затем удалить этоif q is None
предложение - немного менее эффективно, но можно удалить три строки кода. (Пустой Q впоследствии сливается при выполнении запроса.)Другой вариант я не знал до недавнего времени -
QuerySet
также отменяет&
,|
,~
и т.д., операторы. Другие ответы о том, что объекты OR Q являются лучшим решением этого вопроса, но для интереса / аргумента вы можете сделать:str(q.query)
вернет один запрос со всеми фильтрами вWHERE
предложении.источник
Для цикла:
Уменьшить:
Оба они эквивалентны
Article.objects.filter(pk__in=values)
Важно учитывать, что вы хотите, когда
values
пусто. Многие ответы сQ()
начальным значением вернут все .Q(pk__in=[])
- лучшее начальное значение. Это всегда сбойный объект Q, который хорошо обрабатывается оптимизатором (даже для сложных уравнений).Если вы хотите вернуть все, когда
values
оно пусто, вы должны И с помощью,~Q(pk__in=[])
чтобы гарантировать, что поведение:Важно помнить, что
Q()
это ничто , не всегда следующий Q-объект. Любая операция, связанная с этим, просто отбросит его полностью.источник
easy ..
from django.db.models import Q import you model args = (Q (visibility = 1) | (Q (visibility = 0) & Q (user = self.user))) #Tuple parameters = {} #dic order = лимит 'create_at' = 10
источник