__author__ = 'neko259' from django.core.paginator import Paginator PAGINATOR_LOOKAROUND_SIZE = 2 def get_paginator(*args, **kwargs): return DividedPaginator(*args, **kwargs) class DividedPaginator(Paginator): lookaround_size = PAGINATOR_LOOKAROUND_SIZE def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True, current_page=1): super().__init__(object_list, per_page, orphans, allow_empty_first_page) self.link = None self.params = None self.current_page = current_page def _left_range(self): return self.page_range[:self.lookaround_size] def _right_range(self): pages = self.num_pages-self.lookaround_size if pages <= 0: return [] else: return self.page_range[pages:] def _center_range(self): index = self.page_range.index(self.current_page) 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] def get_divided_range(self): dr = list() dr += self._left_range() dr += self._center_range() dr += self._right_range() # Remove duplicates dr = list(set(dr)) dr.sort() return dr def get_dividers(self): dividers = [] prev_page = 1 for page in self.get_divided_range(): if page - prev_page > 1: dividers.append(page) # There can be no more than 2 dividers, so don't bother going # further if len(dividers) > 2: break prev_page = page return dividers def set_url(self, link, params): self.link = link self.params = params def get_page_url(self, page): self.params['page'] = page url_params = '?' + '&'.join(['{}={}'.format(key, self.params[key]) for key in self.params.keys()]) return self.link + url_params def supports_urls(self): return self.link is not None and self.params is not None 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(): return self.get_page_url(current.previous_page_number())