Login

(Modified/Improved) MultiQuerySet

Author:
joonas
Posted:
December 17, 2008
Language:
Python
Version:
1.0
Score:
0 (after 0 ratings)

My modified version of the MultiQuerySet by mattdw (see the link for further information).

My purpose for this was to enable me to combine multiple different types of querysets together, which could then be iterated on as one object (i.e. like a tumblelog).

 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
29
30
31
32
33
34
35
36
37
38
39
40
class MultiQuerySet(object):
    def __init__(self, *args, **kwargs):
        self.querysets = args
        self._count = None
    
    def _clone(self):
        querysets = [qs._clone() for qs in self.querysets]
        return MultiQuerySet(*querysets)
    
    def __repr__(self):
        return repr(list(self.querysets))
                
    def count(self):
        if not self._count:
            self._count = sum([qs.count() for qs in self.querysets])
        return self._count
    
    def __len__(self):
        return self.count()
    
    def __iter__(self):
        for qs in self.querysets:
            for item in qs.all():
                yield item
        
    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

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

nosa_manuel (on December 18, 2008):

It would be nice to have these generated transparently:

class QuerySet(object):
    ...
    def __add__(self, other):
        if isinstance(other, QuerySet):
            return MultiQuerySet(self, other)
        elif isinstance(other, MultiQuerySet):
            querysets = other._clone().querysets
            return MultiQuerySet(self, *querysets)
        else:
            raise TypeError

#

esquevin (on October 19, 2012):

I've fixed a bug in the code that occurred with small querysets on pages > 1, the length of former queryset was substracted from the offset, but not from the stop, resulting in variable length pages

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:offset + total_len - len(items)])
            if len(items) >= total_len:
                return items
            else:
                offset = 0
                continue

#

Please login first before commenting.