En un ejemplo, puede ver un filtro de consulta OR múltiple:
Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Por ejemplo, esto da como resultado:
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
Sin embargo, quiero crear este filtro de consulta a partir de una lista. ¿Como hacer eso?
p.ej [1, 2, 3] -> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Article.objects.filter(pk__in=[1, 2, 3])
en django moderno, pero la pregunta sigue siendo relevante si desea hacer algo un poco más avanzado al combinar objetos Q con OR.Respuestas:
Puede encadenar sus consultas de la siguiente manera:
fuente
Para crear consultas más complejas, también existe la opción de usar las constantes Q.OR y Q.AND del objeto Q () integradas junto con el método add () así:
fuente
q_objects |= Q(pk=item)
list
está vacío, devolverá el equivalente deArticle.objects.all()
. SinArticle.objects.none()
embargo, es fácil de mitigar regresando para esa prueba.q_objects
conQ(id__in=[])
. Siempre fallará a menos que se haga OR con algo y el optimizador de consultas lo manejará bien.Una forma más corta de escribir la respuesta de Dave Webb usando la función de reducción de python :
fuente
functools.reduce
. fuenteoperator.or_
lugar de lambda.fuente
operator
viene el?Tal vez sea mejor usar la instrucción sql IN.
Ver referencia de la API de queryset .
Si realmente necesita hacer consultas con lógica dinámica, puede hacer algo como esto (feo + no probado):
fuente
query |= Q(field=cond)
Ver los documentos :
Tenga en cuenta que este método solo funciona para búsquedas de claves primarias, pero eso parece ser lo que está tratando de hacer.
Entonces lo que quieres es:
fuente
En caso de que queramos establecer programáticamente qué campo de base de datos queremos consultar:
fuente
Solución que utilizan
reduce
yor_
operadores para filtrar por multiplicar campos.ps
f
es un nuevo formato literal de cadenas. Fue introducido en Python 3.6fuente
Puede utilizar el operador | = para actualizar mediante programación una consulta utilizando objetos Q.
fuente
Este es para la lista dinámica de pk:
fuente
q = Q()
lugar deq = None
, luego eliminar laif q is None
cláusula, un poco menos eficiente pero puede eliminar tres líneas de código. (La Q vacía se fusiona posteriormente cuando se ejecuta la consulta)Otra opción que no estaba al tanto de que hasta hace poco -
QuerySet
también anula los&
,|
,~
, etc, operadores. El otro responde que los objetos OR Q son una mejor solución a esta pregunta, pero por el interés / argumento, puede hacer:str(q.query)
devolverá una consulta con todos los filtros de laWHERE
cláusula.fuente
En bucle:
Reducir:
Ambos son equivalentes a
Article.objects.filter(pk__in=values)
Es importante considerar lo que quiere cuando
values
está vacío. Muchas respuestas conQ()
un valor inicial devolverán todo .Q(pk__in=[])
es un mejor valor inicial. Es un objeto Q que falla siempre y que el optimizador maneja bien (incluso para ecuaciones complejas).Si desea devolver todo cuando
values
está vacío, debe Y con~Q(pk__in=[])
para garantizar ese comportamiento:Es importante recordar que no
Q()
es nada , no un objeto Q siempre exitoso. Cualquier operación que lo involucre simplemente lo eliminará por completo.fuente
fácil ...
desde django.db.models import Q importa tu modelo args = (Q (visibilidad = 1) | (Q (visibilidad = 0) & Q (usuario = self.user))) #Tuple parámetros = {} # orden dic = 'crear_en' límite = 10
fuente