1from django.conf import settings 2from django.core.paginator import Paginator, Page 3 4 5class EnhancedPaginator(Paginator): 6 7 def __init__(self, object_list, per_page, orphans=None, **kwargs): 8 9 # Determine the page size 10 try: 11 per_page = int(per_page) 12 if per_page < 1: 13 per_page = settings.PAGINATE_COUNT 14 except ValueError: 15 per_page = settings.PAGINATE_COUNT 16 17 # Set orphans count based on page size 18 if orphans is None and per_page <= 50: 19 orphans = 5 20 elif orphans is None: 21 orphans = 10 22 23 super().__init__(object_list, per_page, orphans=orphans, **kwargs) 24 25 def _get_page(self, *args, **kwargs): 26 return EnhancedPage(*args, **kwargs) 27 28 29class EnhancedPage(Page): 30 31 def smart_pages(self): 32 33 # When dealing with five or fewer pages, simply return the whole list. 34 if self.paginator.num_pages <= 5: 35 return self.paginator.page_range 36 37 # Show first page, last page, next/previous two pages, and current page 38 n = self.number 39 pages_wanted = [1, n - 2, n - 1, n, n + 1, n + 2, self.paginator.num_pages] 40 page_list = sorted(set(self.paginator.page_range).intersection(pages_wanted)) 41 42 # Insert skip markers 43 skip_pages = [x[1] for x in zip(page_list[:-1], page_list[1:]) if (x[1] - x[0] != 1)] 44 for i in skip_pages: 45 page_list.insert(page_list.index(i), False) 46 47 return page_list 48 49 50def get_paginate_count(request): 51 """ 52 Determine the desired length of a page, using the following in order: 53 54 1. per_page URL query parameter 55 2. Saved user preference 56 3. PAGINATE_COUNT global setting. 57 58 Return the lesser of the calculated value and MAX_PAGE_SIZE. 59 """ 60 def _max_allowed(page_size): 61 if settings.MAX_PAGE_SIZE: 62 return min(page_size, settings.MAX_PAGE_SIZE) 63 return page_size 64 65 if 'per_page' in request.GET: 66 try: 67 per_page = int(request.GET.get('per_page')) 68 if request.user.is_authenticated: 69 request.user.config.set('pagination.per_page', per_page, commit=True) 70 return _max_allowed(per_page) 71 except ValueError: 72 pass 73 74 if request.user.is_authenticated: 75 per_page = request.user.config.get('pagination.per_page', settings.PAGINATE_COUNT) 76 return _max_allowed(per_page) 77 78 return _max_allowed(settings.PAGINATE_COUNT) 79