A partir de um exemplo, você pode ver um filtro de consulta OR múltipla:
Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Por exemplo, isso resulta em:
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
No entanto, desejo criar esse filtro de consulta a partir de uma lista. Como fazer isso?
por exemplo [1, 2, 3] -> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Article.objects.filter(pk__in=[1, 2, 3])
no django moderno, mas a questão ainda é relevante se você quiser fazer algo um pouco mais avançado fazendo OR'ing de objetos Q juntos.Respostas:
Você pode encadear suas consultas da seguinte maneira:
fonte
Para construir consultas mais complexas, há também a opção de usar as constantes Q.OR e Q.AND do objeto Q () embutidas junto com o método add () como:
fonte
q_objects |= Q(pk=item)
list
estiver vazio, você retornará o equivalente aArticle.objects.all()
. Fácil de mitigar voltandoArticle.objects.none()
para aquele teste.q_objects
comQ(id__in=[])
. Ele sempre falhará, a menos que seja combinado com algo e o otimizador de consulta lidará bem com isso.Uma maneira mais rápida de escrever a resposta de Dave Webb usando a função de redução do python :
fonte
functools.reduce
. fonteoperator.or_
vez do lambda.fonte
operator
veio?Talvez seja melhor usar a instrução sql IN.
Consulte a referência da API do queryset .
Se você realmente precisa fazer consultas com lógica dinâmica, pode fazer algo assim (feio + não testado):
fonte
query |= Q(field=cond)
Veja a documentação :
Observe que esse método só funciona para pesquisas de chave primária, mas parece ser isso que você está tentando fazer.
Então o que você quer é:
fonte
Caso desejemos definir programaticamente qual campo db queremos consultar:
fonte
Solução que utiliza
reduce
eor_
operadores para filtrar por campos de multiplicação.ps
f
é um novo literal de strings de formato. Foi introduzido no python 3.6fonte
Você pode usar o operador | = para atualizar programaticamente uma consulta usando objetos Q.
fonte
Este é para a lista pk dinâmica:
fonte
q = Q()
vez deq = None
e remover aif q is None
cláusula - um pouco menos eficiente, mas pode remover três linhas de código. (O Q vazio é posteriormente mesclado quando a consulta é executada.)Outra opção que eu não estava ciente de até recentemente -
QuerySet
também substitui os&
,|
,~
, etc, operadores. As outras respostas que os objetos OR Q são uma solução melhor para esta questão, mas por uma questão de interesse / argumento, você pode fazer:str(q.query)
retornará uma consulta com todos os filtros daWHERE
cláusula.fonte
Para loop:
Reduzir:
Ambos são equivalentes a
Article.objects.filter(pk__in=values)
É importante considerar o que você deseja quando
values
está vazio. Muitas respostas comQ()
como valor inicial retornarão tudo .Q(pk__in=[])
é um valor inicial melhor. É um objeto Q que sempre falha que é bem tratado pelo otimizador (mesmo para equações complexas).Se quiser retornar tudo quando
values
estiver vazio, você deve usar E com~Q(pk__in=[])
para garantir esse comportamento:É importante lembrar que não
Q()
é nada , nem um objeto Q sempre bem-sucedido. Qualquer operação que o envolva simplesmente o abandonará completamente.fonte
fácil ..
de django.db.models import Q import você modelar args = (Q (visibilidade = 1) | (Q (visibilidade = 0) & Q (usuário = self.user))) #Tuple parameters = {} #dic order = limite de 'criar_at' = 10
fonte