Pablo D. Waite
Tengo un modelo de Django con dos métodos de administrador personalizados. Cada uno devuelve un subconjunto diferente de los objetos del modelo, en función de una propiedad diferente del objeto.
¿Hay alguna forma de obtener un conjunto de consultas, o simplemente una lista de objetos, esa es la unión de los conjuntos de consultas devueltos por cada método de administrador?
Jordán Reiter
Esto funciona y se ve un poco más limpio:
records = query1 | query2
Si no desea duplicados, deberá agregar .distinct()
:
records = (query1 | query2).distinct()
-
Si bien la respuesta aceptada devuelve una unión iterable (lista para ser exactos), como OP ha pedido, este método devuelve una verdadera unión de conjuntos de consultas. Este conjunto de consultas se puede operar más, lo que se desea en muchas circunstancias.
–Krystian Cybulski
9 de enero de 2013 a las 15:10
-
Debido a un error de Django, esta construcción a veces puede devolver resultados incorrectos cuando se trata de
ManyToManyField
s. Por ejemplo, a veces verás querecords.count()
será mayor quequery1.count() + query2.count()
lo cual es claramente incorrecto.– Jian
24 de abril de 2013 a las 0:00
-
@Jian, ¿puede aclarar la versión de django con el error y un enlace al problema de djangoproject?
– IMFletcher
3 de mayo de 2013 a las 1:59
-
registros = consulta1 | consulta2; records = records.distinct() me daría el resultado correcto
– eugene
31 de mayo de 2013 a las 6:34
-
Puede sobrecargar los operadores en Python. Ver docs.python.org/2/library/operator.html. Entonces, lo que hace Django es crear métodos especiales para el objeto QuerySet. Ver el código aquí: github.com/django/django/blob/master/django/db/models/… la
QuerySet
clase proporciona métodos para__and__
y__or__
que se llaman cuando el&
o|
Los operadores se utilizan entre dosQuerySet
objetos (también utilizados para laQ
clase también).– Jordán Reiter
7 oct 2013 a las 18:11
José Cherián
Empezando desde versión 1.11los conjuntos de consultas de django tienen un método de unión integrado.
q = q1.union(q2) #q will contain all unique records of q1 + q2
q = q1.union(q2, all=True) #q will contain all records of q1 + q2 including duplicates
q = q1.union(q2,q3) # more than 2 queryset union
Mira mi entrada en el blog en esto para más ejemplos.
-
No pude obtener all=True para trabajar. Terminé lanzando mi conjunto de consultas a un conjunto antes de devolverlo al cliente.
–Braden Holt
15 de marzo de 2019 a las 23:32
-
@BradenHolt, all=True, significa que contendrá registros duplicados. Simplemente puede eliminar all=True para evitar convertirlo en un conjunto.
– José Cherián
16 de marzo de 2019 a las 20:26
-
después de esto, DjangoFilterBackend no funciona, ¿cómo puedo usar union y DjangoFilterBackend?
– nesalexia
29 de agosto de 2019 a las 17:59
-
Desafortunadamente, esto no parece funcionar para modelos con un orden predeterminado definido en el Meta del modelo. Cada vez que trato de combinarlos con .union, recibo el siguiente error: “ORDER BY no permitido en subconsultas de declaraciones compuestas”.
– jrial
15 de noviembre de 2019 a las 14:29
xian xing
Yo sugeriría usar ‘query1.union(query2)’ en lugar de ‘query1 | consulta2’; Obtuve resultados diferentes de los dos métodos anteriores y el primero es lo que esperaba. Lo siguiente es lo que me había encontrado:
print "union result:"
for element in query_set1.union(query_set2):
print element
print "| result:"
for element in (query_set1 | query_set2):
print element
resultado:
union result:
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object
| result:
KafkaTopic object
KafkaTopic object
(De una respuesta eliminada) Consulte esta pregunta para ver una variación que funciona con QuerySets de diferentes modelos: stackoverflow.com/questions/431628/…
– rnevio
21 de marzo de 2016 a las 13:20
A partir de la versión 1.11, los conjuntos de consultas de Django tienen un método de unión incorporado. Lo he agregado como respuesta para futuras referencias.
– José Cherián
9 de agosto de 2017 a las 1:44