18 | | def __init__(self, query_set, num_per_page, orphans=0): |
| 18 | |
| 19 | def __init__(self, query_set, num_per_page=10, orphans=0, page=1): |
| 20 | """ |
| 21 | Initialize the ObjectPaginator instance. |
| 22 | |
| 23 | Parameters:: |
| 24 | * ``query_set`` -- A QuerySet or sequence of objects to paginate. |
| 25 | * ``num_per_page`` -- The number of objects to put on a page. |
| 26 | By default, ``num_per_page`` is 10. |
| 27 | * ``orphans`` -- The number of objects to not put by themselves on |
| 28 | the last page. For example, if ``orphans`` is 2 |
| 29 | and the total number of objects would normally |
| 30 | result in two items on the last page, place those |
| 31 | items on the previous page instead of leaving them |
| 32 | "dangling" on the last page. By default, |
| 33 | ``orphans`` is 0. |
| 34 | * ``page`` -- The page number to initialize the ObjectPaginator |
| 35 | instance to. ``page`` is 1 by default, meaning that |
| 36 | the ObjectPaginator instance will start on the first |
| 37 | page. ``page`` may be an integer or the string |
| 38 | representation of an interger, which is useful when |
| 39 | passing directly from a URL query string. |
| 40 | """ |
35 | | bottom = page_number * self.num_per_page |
36 | | top = bottom + self.num_per_page |
37 | | if top + self.orphans >= self.hits: |
38 | | top = self.hits |
39 | | return self.query_set[bottom:top] |
40 | | |
| 86 | self._page = page_number |
| 87 | |
| 88 | page = property(_get_page, _set_page) |
| 89 | |
| 90 | def _get_first_page(self): |
| 91 | """ |
| 92 | Return the (1-based) page number of the first page. |
| 93 | """ |
| 94 | return 1 |
| 95 | |
| 96 | first_page = property(_get_first_page) |
| 97 | |
| 98 | def _get_last_page(self): |
| 99 | """ |
| 100 | Return the (1-based) page number of the last page. |
| 101 | """ |
| 102 | return self.pages |
| 103 | |
| 104 | last_page = property(_get_last_page) |
| 105 | |
| 106 | def _get_pages(self): |
| 107 | """ |
| 108 | Return the total number of pages. |
| 109 | """ |
| 110 | hits = max(self.hits - self.orphans - 1, 0) |
| 111 | return hits // self.num_per_page + 1 |
| 112 | |
| 113 | pages = property(_get_pages) |
| 114 | |
| 115 | def has_page(self, page_number): |
| 116 | """ |
| 117 | Return true if the paginator has the passed page_number, and False |
| 118 | otherwise. |
| 119 | """ |
| 120 | return self.first_page <= page_number <= self.last_page |
| 121 | |
| 122 | def next_page(self, page_number=None): |
| 123 | """ |
| 124 | Return the page number of the page after the passed page_number. |
| 125 | If page_number is not given, then use the current page. |
| 126 | If there is no next page, then return None. |
| 127 | """ |
| 128 | if page_number is None: |
| 129 | page_number = self.page |
| 130 | else: |
| 131 | page_number = self.validate_page_number(page_number) |
| 132 | next_page = self.page + 1 |
| 133 | if self.has_page(next_page): |
| 134 | return next_page |
| 135 | |
42 | | "Does page $page_number have a 'next' page?" |
43 | | return page_number < self.pages - 1 |
44 | | |
| 137 | """ |
| 138 | Return True if the passed page_number has a next page, and False |
| 139 | otherwise. If page_number is not given, then use the current page. |
| 140 | """ |
| 141 | return self.next_page(page_number) is not None |
| 142 | |
| 143 | def previous_page(self, page_number=None): |
| 144 | """ |
| 145 | Return the page number of the page before the passed page_number. |
| 146 | If page_number is not given, then use the current page. |
| 147 | If there is no previous page, then return None. |
| 148 | """ |
| 149 | if page_number is None: |
| 150 | page_number = self.page |
| 151 | else: |
| 152 | page_number = self.validate_page_number(page_number) |
| 153 | previous_page = self.page - 1 |
| 154 | if self.has_page(previous_page): |
| 155 | return previous_page |
| 156 | |
88 | | pages = property(_get_pages) |
| 208 | |
| 209 | def get_items(self, page_number=None): |
| 210 | """ |
| 211 | Return the slice of items for the passed (1-based) page_number. |
| 212 | If page_number is not given, then use the current page. |
| 213 | """ |
| 214 | if page_number is None: |
| 215 | page_number = self.page |
| 216 | else: |
| 217 | page_number = self.validate_page_number(page_number) |
| 218 | bottom = (page_number - 1)* self.num_per_page |
| 219 | # Special handling of orphans on the last page. |
| 220 | if page_number is self.last_page: |
| 221 | top = self.hits |
| 222 | else: |
| 223 | top = bottom + self.num_per_page |
| 224 | return self.query_set[bottom:top] |
| 225 | |
| 226 | def get_page(self, page_number): |
| 227 | """ |
| 228 | This function was kept to keep backwards compatibility. |
| 229 | Return the slice of items for the passed (0-based) page_number. |
| 230 | """ |
| 231 | return self.get_items(page_number + 1) |