Django

Code

root/django/trunk/django/core/paginator.py

Revision 8191, 3.9 kB (checked in by gwilson, 4 months ago)

Removed several deprecated features for 1.0 (refs #7830):

  • "simple" cache backend
  • ObjectPaginator
  • edit_inline_type argument for ForeignKey fields
  • QOperator, QNot, QAnd and QOr
  • maxlength argument
  • Property svn:eol-style set to native
  • Property svn:keywords set to LastChangedRevision
Line 
1 from math import ceil
2
3 class InvalidPage(Exception):
4     pass
5
6 class PageNotAnInteger(InvalidPage):
7     pass
8
9 class EmptyPage(InvalidPage):
10     pass
11
12 class Paginator(object):
13     def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True):
14         self.object_list = object_list
15         self.per_page = per_page
16         self.orphans = orphans
17         self.allow_empty_first_page = allow_empty_first_page
18         self._num_pages = self._count = None
19
20     def validate_number(self, number):
21         "Validates the given 1-based page number."
22         try:
23             number = int(number)
24         except ValueError:
25             raise PageNotAnInteger('That page number is not an integer')
26         if number < 1:
27             raise EmptyPage('That page number is less than 1')
28         if number > self.num_pages:
29             if number == 1 and self.allow_empty_first_page:
30                 pass
31             else:
32                 raise EmptyPage('That page contains no results')
33         return number
34
35     def page(self, number):
36         "Returns a Page object for the given 1-based page number."
37         number = self.validate_number(number)
38         bottom = (number - 1) * self.per_page
39         top = bottom + self.per_page
40         if top + self.orphans >= self.count:
41             top = self.count
42         return Page(self.object_list[bottom:top], number, self)
43
44     def _get_count(self):
45         "Returns the total number of objects, across all pages."
46         if self._count is None:
47             try:
48                 self._count = self.object_list.count()
49             except (AttributeError, TypeError):
50                 # AttributeError if object_list has no count() method.
51                 # TypeError if object_list.count() requires arguments
52                 # (i.e. is of type list).
53                 self._count = len(self.object_list)
54         return self._count
55     count = property(_get_count)
56
57     def _get_num_pages(self):
58         "Returns the total number of pages."
59         if self._num_pages is None:
60             if self.count == 0 and not self.allow_empty_first_page:
61                 self._num_pages = 0
62             else:
63                 hits = max(1, self.count - self.orphans)
64                 self._num_pages = int(ceil(hits / float(self.per_page)))
65         return self._num_pages
66     num_pages = property(_get_num_pages)
67
68     def _get_page_range(self):
69         """
70         Returns a 1-based range of pages for iterating through within
71         a template for loop.
72         """
73         return range(1, self.num_pages + 1)
74     page_range = property(_get_page_range)
75
76 QuerySetPaginator = Paginator # For backwards-compatibility.
77
78 class Page(object):
79     def __init__(self, object_list, number, paginator):
80         self.object_list = object_list
81         self.number = number
82         self.paginator = paginator
83
84     def __repr__(self):
85         return '<Page %s of %s>' % (self.number, self.paginator.num_pages)
86
87     def has_next(self):
88         return self.number < self.paginator.num_pages
89
90     def has_previous(self):
91         return self.number > 1
92
93     def has_other_pages(self):
94         return self.has_previous() or self.has_next()
95
96     def next_page_number(self):
97         return self.number + 1
98
99     def previous_page_number(self):
100         return self.number - 1
101
102     def start_index(self):
103         """
104         Returns the 1-based index of the first object on this page,
105         relative to total objects in the paginator.
106         """
107         # Special case, return zero if no items.
108         if self.paginator.count == 0:
109             return 0
110         return (self.paginator.per_page * (self.number - 1)) + 1
111
112     def end_index(self):
113         """
114         Returns the 1-based index of the last object on this page,
115         relative to total objects found (hits).
116         """
117         # Special case for the last page because there can be orphans.
118         if self.number == self.paginator.num_pages:
119             return self.paginator.count
120         return self.number * self.paginator.per_page
Note: See TracBrowser for help on using the browser.