paginator.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from django.core.paginator import Paginator, Page
  2. from netbox.config import get_config
  3. __all__ = (
  4. 'EnhancedPage',
  5. 'EnhancedPaginator',
  6. 'get_paginate_count',
  7. )
  8. class EnhancedPaginator(Paginator):
  9. default_page_lengths = (
  10. 25, 50, 100, 250, 500, 1000
  11. )
  12. def __init__(self, object_list, per_page, orphans=None, **kwargs):
  13. # Determine the page size
  14. try:
  15. per_page = int(per_page)
  16. if per_page < 1:
  17. per_page = get_config().PAGINATE_COUNT
  18. except ValueError:
  19. per_page = get_config().PAGINATE_COUNT
  20. # Set orphans count based on page size
  21. if orphans is None and per_page <= 50:
  22. orphans = 5
  23. elif orphans is None:
  24. orphans = 10
  25. super().__init__(object_list, per_page, orphans=orphans, **kwargs)
  26. def _get_page(self, *args, **kwargs):
  27. return EnhancedPage(*args, **kwargs)
  28. def get_page_lengths(self):
  29. if self.per_page not in self.default_page_lengths:
  30. return sorted([*self.default_page_lengths, self.per_page])
  31. return self.default_page_lengths
  32. class EnhancedPage(Page):
  33. def smart_pages(self):
  34. # When dealing with five or fewer pages, simply return the whole list.
  35. if self.paginator.num_pages <= 5:
  36. return self.paginator.page_range
  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. # Insert skip markers
  42. skip_pages = [x[1] for x in zip(page_list[:-1], page_list[1:]) if (x[1] - x[0] != 1)]
  43. for i in skip_pages:
  44. page_list.insert(page_list.index(i), False)
  45. return page_list
  46. def get_paginate_count(request):
  47. """
  48. Determine the desired length of a page, using the following in order:
  49. 1. per_page URL query parameter
  50. 2. Saved user preference
  51. 3. PAGINATE_COUNT global setting.
  52. Return the lesser of the calculated value and MAX_PAGE_SIZE.
  53. """
  54. config = get_config()
  55. def _max_allowed(page_size):
  56. if config.MAX_PAGE_SIZE:
  57. return min(page_size, config.MAX_PAGE_SIZE)
  58. return page_size
  59. if 'per_page' in request.GET:
  60. try:
  61. per_page = int(request.GET.get('per_page'))
  62. return _max_allowed(per_page)
  63. except ValueError:
  64. pass
  65. if request.user.is_authenticated:
  66. per_page = request.user.config.get('pagination.per_page', config.PAGINATE_COUNT)
  67. return _max_allowed(per_page)
  68. return _max_allowed(config.PAGINATE_COUNT)