paginator.py
107 lines
| 3.1 KiB
| text/x-python
|
PythonLexer
neko259
|
r2061 | from django.core.paginator import Paginator | ||
neko259
|
r2035 | from boards.abstracts.constants import PARAM_PAGE | ||
neko259
|
r722 | __author__ = 'neko259' | ||
neko259
|
r596 | |||
neko259
|
r2061 | PATTERN_PAGE_URL = '<a {} href="{}">{}</a>' | ||
neko259
|
r1199 | PAGINATOR_LOOKAROUND_SIZE = 2 | ||
neko259
|
r596 | |||
def get_paginator(*args, **kwargs): | ||||
return DividedPaginator(*args, **kwargs) | ||||
class DividedPaginator(Paginator): | ||||
lookaround_size = PAGINATOR_LOOKAROUND_SIZE | ||||
neko259
|
r1419 | |||
def __init__(self, object_list, per_page, orphans=0, | ||||
neko259
|
r2061 | allow_empty_first_page=True, current_page=1, link=None, params=None): | ||
neko259
|
r1419 | super().__init__(object_list, per_page, orphans, allow_empty_first_page) | ||
neko259
|
r2061 | self.link = link | ||
self.params = params | ||||
neko259
|
r1419 | self.current_page = current_page | ||
neko259
|
r596 | |||
neko259
|
r1200 | def _left_range(self): | ||
neko259
|
r1199 | return self.page_range[:self.lookaround_size] | ||
neko259
|
r1200 | def _right_range(self): | ||
neko259
|
r1199 | pages = self.num_pages-self.lookaround_size | ||
if pages <= 0: | ||||
return [] | ||||
else: | ||||
return self.page_range[pages:] | ||||
neko259
|
r1200 | def _center_range(self): | ||
neko259
|
r596 | index = self.page_range.index(self.current_page) | ||
neko259
|
r1199 | start = max(self.lookaround_size, index - self.lookaround_size) | ||
end = min(self.num_pages - self.lookaround_size, index + self.lookaround_size + 1) | ||||
return self.page_range[start:end] | ||||
neko259
|
r2063 | def _get_divided_range(self): | ||
neko259
|
r1199 | dr = list() | ||
neko259
|
r1200 | dr += self._left_range() | ||
dr += self._center_range() | ||||
dr += self._right_range() | ||||
neko259
|
r1199 | |||
# Remove duplicates | ||||
dr = list(set(dr)) | ||||
dr.sort() | ||||
return dr | ||||
neko259
|
r2063 | def get_dividers(self, divided_range): | ||
neko259
|
r1200 | dividers = [] | ||
prev_page = 1 | ||||
neko259
|
r2063 | for page in divided_range: | ||
neko259
|
r1200 | if page - prev_page > 1: | ||
dividers.append(page) | ||||
neko259
|
r1199 | |||
neko259
|
r1200 | # There can be no more than 2 dividers, so don't bother going | ||
# further | ||||
if len(dividers) > 2: | ||||
break | ||||
prev_page = page | ||||
neko259
|
r1199 | |||
neko259
|
r1200 | return dividers | ||
neko259
|
r1377 | |||
def get_page_url(self, page): | ||||
neko259
|
r2035 | self.params[PARAM_PAGE] = page | ||
url_params = '&'.join(['{}={}'.format(key, self.params[key]) | ||||
for key in self.params.keys()]) | ||||
return '{}?{}'.format(self.link, url_params) | ||||
neko259
|
r1377 | |||
neko259
|
r1379 | def supports_urls(self): | ||
return self.link is not None and self.params is not None | ||||
neko259
|
r1419 | |||
def get_next_page_url(self): | ||||
current = self.page(self.current_page) | ||||
if current.has_next(): | ||||
return self.get_page_url(current.next_page_number()) | ||||
def get_prev_page_url(self): | ||||
current = self.page(self.current_page) | ||||
if current.has_previous(): | ||||
neko259
|
r2035 | return self.get_page_url(current.previous_page_number()) | ||
neko259
|
r2061 | |||
def get_page_url_list(self): | ||||
output = [] | ||||
neko259
|
r2063 | divided_range = self._get_divided_range() | ||
dividers = self.get_dividers(divided_range) | ||||
for page in divided_range: | ||||
neko259
|
r2061 | if page in dividers: | ||
output.append('...') | ||||
if page == self.current_page: | ||||
neko259
|
r2062 | cls = 'class="current_page"' | ||
neko259
|
r2061 | else: | ||
cls = '' | ||||
output.append(PATTERN_PAGE_URL.format(cls, self.get_page_url(page), | ||||
page)) | ||||
return ', '.join(output) | ||||