summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorNick Pope <nick.pope@flightdataservices.com>2020-08-06 11:43:42 +0200
committerCarlton Gibson <carlton@noumenal.es>2020-08-06 12:38:56 +0200
commit0a306f7da668e53af2516bfad759b52d6c650b69 (patch)
treeb60b7e9b534d95830c6afd1f6bc39d0791d79b25 /django
parentf35840c19664fed7b6bc4cf561bf0b6fd1a3b463 (diff)
Fixed #25513 -- Extracted admin pagination to Paginator.get_elided_page_range().
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/templatetags/admin_list.py39
-rw-r--r--django/core/paginator.py34
2 files changed, 37 insertions, 36 deletions
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 5c8d21d30d..f4b6d8d59f 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -24,16 +24,14 @@ from .base import InclusionAdminNode
register = Library()
-DOT = '.'
-
@register.simple_tag
def paginator_number(cl, i):
"""
Generate an individual page index link in a paginated list.
"""
- if i == DOT:
- return '… '
+ if i == cl.paginator.ELLIPSIS:
+ return format_html('{} ', cl.paginator.ELLIPSIS)
elif i == cl.page_num:
return format_html('<span class="this-page">{}</span> ', i)
else:
@@ -49,39 +47,8 @@ def pagination(cl):
"""
Generate the series of links to the pages in a paginated list.
"""
- paginator, page_num = cl.paginator, cl.page_num
-
pagination_required = (not cl.show_all or not cl.can_show_all) and cl.multi_page
- if not pagination_required:
- page_range = []
- else:
- ON_EACH_SIDE = 3
- ON_ENDS = 2
-
- # If there are 10 or fewer pages, display links to every page.
- # Otherwise, do some fancy
- if paginator.num_pages <= 10:
- page_range = range(1, paginator.num_pages + 1)
- else:
- # Insert "smart" pagination links, so that there are always ON_ENDS
- # links at either end of the list of pages, and there are always
- # ON_EACH_SIDE links at either end of the "current page" link.
- page_range = []
- if page_num > (1 + ON_EACH_SIDE + ON_ENDS) + 1:
- page_range += [
- *range(1, ON_ENDS + 1), DOT,
- *range(page_num - ON_EACH_SIDE, page_num + 1),
- ]
- else:
- page_range.extend(range(1, page_num + 1))
- if page_num < (paginator.num_pages - ON_EACH_SIDE - ON_ENDS) - 1:
- page_range += [
- *range(page_num + 1, page_num + ON_EACH_SIDE + 1), DOT,
- *range(paginator.num_pages - ON_ENDS + 1, paginator.num_pages + 1)
- ]
- else:
- page_range.extend(range(page_num + 1, paginator.num_pages + 1))
-
+ page_range = cl.paginator.get_elided_page_range(cl.page_num) if pagination_required else []
need_show_all_link = cl.can_show_all and not cl.show_all and cl.multi_page
return {
'cl': cl,
diff --git a/django/core/paginator.py b/django/core/paginator.py
index ec0ebe0403..7db64913d9 100644
--- a/django/core/paginator.py
+++ b/django/core/paginator.py
@@ -25,6 +25,9 @@ class EmptyPage(InvalidPage):
class Paginator:
+ # Translators: String used to replace omitted page numbers in elided page
+ # range generated by paginators, e.g. [1, 2, '…', 5, 6, 7, '…', 9, 10].
+ ELLIPSIS = _('…')
def __init__(self, object_list, per_page, orphans=0,
allow_empty_first_page=True):
@@ -128,6 +131,37 @@ class Paginator:
stacklevel=3
)
+ def get_elided_page_range(self, number=1, *, on_each_side=3, on_ends=2):
+ """
+ Return a 1-based range of pages with some values elided.
+
+ If the page range is larger than a given size, the whole range is not
+ provided and a compact form is returned instead, e.g. for a paginator
+ with 50 pages, if page 43 were the current page, the output, with the
+ default arguments, would be:
+
+ 1, 2, …, 40, 41, 42, 43, 44, 45, 46, …, 49, 50.
+ """
+ number = self.validate_number(number)
+
+ if self.num_pages <= (on_each_side + on_ends) * 2:
+ yield from self.page_range
+ return
+
+ if number > (1 + on_each_side + on_ends) + 1:
+ yield from range(1, on_ends + 1)
+ yield self.ELLIPSIS
+ yield from range(number - on_each_side, number + 1)
+ else:
+ yield from range(1, number + 1)
+
+ if number < (self.num_pages - on_each_side - on_ends) - 1:
+ yield from range(number + 1, number + on_each_side + 1)
+ yield self.ELLIPSIS
+ yield from range(self.num_pages - on_ends + 1, self.num_pages + 1)
+ else:
+ yield from range(number + 1, self.num_pages + 1)
+
class Page(collections.abc.Sequence):