2010-12-10 15 views
50

J'ai un modèle Django avec deux méthodes de gestion personnalisées. Chacun renvoie un sous-ensemble différent des objets du modèle, basé sur une propriété différente de l'objet.Comment puis-je trouver l'union de deux querysets Django?

Existe-t-il un moyen d'obtenir un ensemble de requêtes, ou simplement une liste d'objets, qui correspond à l'union des ensembles de requêtes retournés par chaque méthode de gestion?

+2

(d'une réponse supprimée) Voir cette question pour une variation qui fonctionne avec QuerySets de différents modèles: http://stackoverflow.com/questions/431628/how-to-combine-2-or-more-querysets-in -a-django-view – rnevius

+1

À partir de la version 1.11, les ensembles de requêtes django ont une méthode d'union interne. Je l'ai ajouté comme réponse pour référence future –

Répondre

127

Cela fonctionne et ressemble un peu plus propre:

records = query1 | query2 

Si vous ne voulez pas de doublons, alors vous aurez besoin d'ajouter .distinct():

records = (query1 | query2).distinct() 
+4

Alors que la réponse acceptée renvoie une union itérable (liste à être exacte), comme OP l'a demandé, cette méthode renvoie une véritable union de jeux de requête. Ce queryset peut être actionné plus loin, ce qui est souhaité dans de nombreuses circonstances. –

+4

En raison d'un bug Django, cette construction peut parfois retourner des résultats incorrects en traitant 'ManyToManyField's. Par exemple, vous verrez parfois que 'records.count()' sera plus grand que 'query1.count() + query2.count()', ce qui est clairement incorrect. – Jian

+4

@Jian pouvez-vous clarifier la version django avec le bug et un lien vers le problème de djangoproject? – IMFletcher

16

A partir de version 1.11, QuerySets django ont méthode d'union intégrée.

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 

Voir mon blog post pour plus d'exemples.