tags:

views:

26

answers:

1

I've been searching for a way to take the union of querysets in django. From what I read you can use query1 | query2 to take the union... This doesn't seem to work when using values() though. I'd skip using values until after taking the union but I need to use annotate to take the sum of a field and filter on it and since there's no way to do "group by" I have to use values(). The other suggestions I read were to use Q objects but I can't think of a way that would work.

Do I pretty much need to just use straight SQL or is there a django way of doing this?

What I want is:

q1 = mymodel.objects.filter(date__lt = '2010-06-11').values('field1','field2').annotate(volsum=Sum('volume')).exclude(volsum=0)
q2 = mymodel.objects.values('field1','field2').annotate(volsum=Sum('volume')).exclude(volsum=0)
query = q1|q2

But this doesn't work and as far as I know I need the "values" part because there's no other way for Sum to know how to act since it's a 15 column table.

+1  A: 

QuerySet.values() does not return a QuerySet, but rather a ValuesQuerySet, which does not support this operation. Convert them to lists then add them.

query = list(q1) + list(q2)
Ignacio Vazquez-Abrams
That's a bit different than union... If there's overlap on q1 and q2 I'd end up with duplicate entries in query. I tried set(q1) | set(q2) but dictionaries are natively hashable.
Wuxab
There's quite a few techniques for getting a proper union of two lists in Python here, even with unhashable types. Or in the worst case you could use a Schwartzian transform and put them all in a dict. http://en.wikipedia.org/wiki/Schwartzian_transform
Ignacio Vazquez-Abrams