1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class MultiQuerySet(object):
def __init__(self, *args, **kwargs):
self.querysets = args
self._count = None
def count(self):
if not self._count:
self._count = sum(len(qs) for qs in self.querysets)
return self._count
def __len__(self):
return self.count()
def __getitem__(self, item):
indices = (offset, stop, step) = item.indices(self.count())
items = []
total_len = stop - offset
for qs in self.querysets:
if len(qs) < offset:
offset -= len(qs)
else:
items += list(qs[offset:stop])
if len(items) >= total_len:
return items
else:
offset = 0
stop = total_len - len(items)
continue
|
More like this
- Multiple querysets by t_rybik 3 years, 3 months ago
- Pagination/Filtering Alphabetically by zain 4 years, 2 months ago
- (Modified/Improved) MultiQuerySet by joonas 4 years, 5 months ago
- sort_by_id_sequence by simon 5 years ago
- Custom managers with chainable filters by itavor 5 years, 4 months ago
Comments
qs = Event.objects.filter(## title matches ##) | Event.objects.filter(## matches in other fields ##)
#
just kidding (wish there was a comment delete)
#
Heh... thanks, ericflo. Fair suggestion, and
qs = qs1 | qs2will probably cover 90% of cases. This is for the other 10% ;-).#
Hm. If you don't need full query set functionality, you might want to consider itertools, which has the nice added bonus you don't even need to use query_sets for the same model. e.g.
(assuming BlogPosts and Events both have a field called 'slug')
that also gets you your original order query set as a special case, and it's very clean.
#
Mine doesn't require querysets to be from the same model either. I looked at
itertools.chain, but it doesn't support enough QuerySet functionality to work with django's pagination module, pagination being one of the requirements of this solution. (In particular, there's no way to a. find the length of achained iterator, or b. slice it arbitrarily. This class supports both of those.)#
Very handy! I've had this exact need before, always worked around it. Nicely done!
#
Is is exactly what I been looking for. Thanks
#
See also answers to "How to combine 2 or more querysets in a Django view?" on StackOverflow for other possible solutions.
Also, mattdw seems to provide a significantly more comprehensive version of this snippet in snippet 1933.
#