diff --git a/django/core/paginator.py b/django/core/paginator.py index fededc4c57..6e01c1ccec 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -6,24 +6,17 @@ class InvalidPage(Exception): class ObjectPaginator: """ - This class makes pagination easy. Feed it a manager (an object with - get_count() and get_list() methods) or a model which has a default manager, - and a dictionary of arguments to be passed to those methods, plus the - number of objects you want on each page. Then read the hits and pages - properties to see how many pages it involves. Call get_page with a page - number (starting at 0) to get back a list of objects for that page. - + This class makes pagination easy. Feed it a QuerySet, plus the number of + objects you want on each page. Then read the hits and pages properties to + see how many pages it involves. Call get_page with a page number (starting + at 0) to get back a list of objects for that page. + Finally, check if a page number has a next/prev page using has_next_page(page_number) and has_previous_page(page_number). """ - def __init__(self, manager_or_model, args, num_per_page, count_method='count', list_method='all'): - if hasattr(manager_or_model, '_default_manager'): - manager = manager_or_model._default_manager - else: - manager = manager_or_model - self.manager, self.args = manager, args + def __init__(self, query_set, num_per_page): + self.query_set = query_set self.num_per_page = num_per_page - self.count_method, self.list_method = count_method, list_method self._hits, self._pages = None, None self._has_next = {} # Caches page_number -> has_next_boolean @@ -34,14 +27,17 @@ class ObjectPaginator: raise InvalidPage if page_number < 0: raise InvalidPage - args = copy(self.args) - args['offset'] = page_number * self.num_per_page + # Retrieve one extra record, and check for the existence of that extra # record to determine whether there's a next page. - args['limit'] = self.num_per_page + 1 - object_list = getattr(self.manager, self.list_method)(**args) + limit = self.num_per_page + 1 + offset = page_number * self.num_per_page + + object_list = list(self.query_set[offset:offset+limit]) + if not object_list: raise InvalidPage + self._has_next[page_number] = (len(object_list) > self.num_per_page) return object_list[:self.num_per_page] @@ -49,11 +45,8 @@ class ObjectPaginator: "Does page $page_number have a 'next' page?" if not self._has_next.has_key(page_number): if self._pages is None: - args = copy(self.args) - args['offset'] = (page_number + 1) * self.num_per_page - args['limit'] = 1 - object_list = getattr(self.manager, self.list_method)(**args) - self._has_next[page_number] = (object_list != []) + offset = (page_number + 1) * self.num_per_page + self._has_next[page_number] = len(self.query_set[offset:offset+1]) > 0 else: self._has_next[page_number] = page_number < (self.pages - 1) return self._has_next[page_number] @@ -63,12 +56,7 @@ class ObjectPaginator: def _get_hits(self): if self._hits is None: - order_args = copy(self.args) - if order_args.has_key('order_by'): - del order_args['order_by'] - if order_args.has_key('select_related'): - del order_args['select_related'] - self._hits = getattr(self.manager, self.count_method)(**order_args) + self._hits = self.query_set.count() return self._hits def _get_pages(self):