Consider two QuerySet objects of the same class. Is there a simple way to unify them into a single QuerySet by calculating the union? Also, is there a simple way to subtract the
You can use the Q object.
The syntax could be something like this:
added_query_set = YourModel.objects.\
filter(Q(id__in=old_query_set_1)|Q(id__in=old_query_set_2))
You probably can optimize based on your actual needs and get the amount of db hits down (right now it's 3), but this should get you started.
Subtract a QuerySet from another QuerySet using the same model.
This works - but is probably slowly
queryset_with_hello = Blog.objects.filter(name__icontains='hello')
queryset_without_hello = Blog.objects.exclude(pk__in=queryset_with_hello)
Read the performance considerations in django documentation:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#in
I think for operations as this you need to evalute them. So you can call list()
on them and work on them with the common python list operations!
Going back to django's documentation, you can:
new_query_set = query_set_1 | query_set_2
This works as a logical OR which is actually addition without duplicates. This answers the addition aspect and AFAIK does not hit the db at all!
new_query_set = query_set_1 & query_set_2
This works as a logical AND.
Still missing how to subtract QuerySets. It's hard for me to believe this has not been dealt with elegantly by the community...
Since Django 1.11, QuerySets have union(), intersection() and difference() methods.
It's also possible to use & and | operators with QuerySets (I could not find a reference to this in the docs, so I guess union()
and intersection()
is the preferred way to combine two querysets.
qs3 = qs1.union(qs2) # or qs3 = qs1 | qs2
qs3 = qs1.intersection(qs2) # or qs3 = qs1 & qs2
qs3 = qs1.difference(qs2) # the ^ operator is not implemented.
You can also use Q() objects which like QuerySets implement |
and &
, and additionally the inversion operator ~