Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find the intersection of two Django querysets?

I’ve got a Django model with two custom manager methods. Each returns a different subset of the model’s objects, based on a different property of the object.

class FeatureManager(models.Manager):

    def without_test_cases(self):
        return self.get_query_set().annotate(num_test_cases=models.Count('testcase_set')).filter(num_test_cases=0)

    def standardised(self):
        return self.get_query_set().annotate(standardised=Count('documentation_set__standard')).filter(standardised__gt=0)

(Both testcase_set and documentation_set refer to ManyToManyFields on other models.)

Is there any way to get a queryset, or just a list of objects, that’s the intersectiond of the querysets returned by each manager method?

like image 920
Paul D. Waite Avatar asked Dec 10 '10 16:12

Paul D. Waite


3 Answers

You can just do something like this:

intersection = queryset1 & queryset2

To do a union just replace & by |

like image 36
Caumons Avatar answered Nov 04 '22 03:11

Caumons


In most cases you can just write (exploiting the "Set" part of QuerySet) :

intersection = Model.objects.filter(...) & Model.objects.filter(...)

This isn't very well documented, but should behave almost exactly like using AND conditions on conditions from both queries. Relevant code: https://github.com/django/django/blob/1.8c1/django/db/models/query.py#L203

like image 53
lqc Avatar answered Nov 04 '22 02:11

lqc


As per Django 1.11, now it's available the function intersection()

>>> qs1.intersection(qs2, qs3)
like image 25
renno Avatar answered Nov 04 '22 03:11

renno