Refs #25513 -- Adjusted admin pagination to be 1-indexed.
This commit is contained in:
parent
ee1ddcbab9
commit
b203ec70fd
|
@ -35,13 +35,13 @@ def paginator_number(cl, i):
|
||||||
if i == DOT:
|
if i == DOT:
|
||||||
return '… '
|
return '… '
|
||||||
elif i == cl.page_num:
|
elif i == cl.page_num:
|
||||||
return format_html('<span class="this-page">{}</span> ', i + 1)
|
return format_html('<span class="this-page">{}</span> ', i)
|
||||||
else:
|
else:
|
||||||
return format_html(
|
return format_html(
|
||||||
'<a href="{}"{}>{}</a> ',
|
'<a href="{}"{}>{}</a> ',
|
||||||
cl.get_query_string({PAGE_VAR: i}),
|
cl.get_query_string({PAGE_VAR: i}),
|
||||||
mark_safe(' class="end"' if i == cl.paginator.num_pages - 1 else ''),
|
mark_safe(' class="end"' if i == cl.paginator.num_pages else ''),
|
||||||
i + 1,
|
i,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,26 +61,26 @@ def pagination(cl):
|
||||||
# If there are 10 or fewer pages, display links to every page.
|
# If there are 10 or fewer pages, display links to every page.
|
||||||
# Otherwise, do some fancy
|
# Otherwise, do some fancy
|
||||||
if paginator.num_pages <= 10:
|
if paginator.num_pages <= 10:
|
||||||
page_range = range(paginator.num_pages)
|
page_range = range(1, paginator.num_pages + 1)
|
||||||
else:
|
else:
|
||||||
# Insert "smart" pagination links, so that there are always ON_ENDS
|
# Insert "smart" pagination links, so that there are always ON_ENDS
|
||||||
# links at either end of the list of pages, and there are always
|
# 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.
|
# ON_EACH_SIDE links at either end of the "current page" link.
|
||||||
page_range = []
|
page_range = []
|
||||||
if page_num > (ON_EACH_SIDE + ON_ENDS):
|
if page_num > (1 + ON_EACH_SIDE + ON_ENDS):
|
||||||
page_range += [
|
page_range += [
|
||||||
*range(0, ON_ENDS), DOT,
|
*range(1, ON_ENDS + 1), DOT,
|
||||||
*range(page_num - ON_EACH_SIDE, page_num + 1),
|
*range(page_num - ON_EACH_SIDE, page_num + 1),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
page_range.extend(range(0, page_num + 1))
|
page_range.extend(range(1, page_num + 1))
|
||||||
if page_num < (paginator.num_pages - ON_EACH_SIDE - ON_ENDS - 1):
|
if page_num < (paginator.num_pages - ON_EACH_SIDE - ON_ENDS):
|
||||||
page_range += [
|
page_range += [
|
||||||
*range(page_num + 1, page_num + ON_EACH_SIDE + 1), DOT,
|
*range(page_num + 1, page_num + ON_EACH_SIDE + 1), DOT,
|
||||||
*range(paginator.num_pages - ON_ENDS, paginator.num_pages)
|
*range(paginator.num_pages - ON_ENDS + 1, paginator.num_pages + 1)
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
page_range.extend(range(page_num + 1, paginator.num_pages))
|
page_range.extend(range(page_num + 1, paginator.num_pages + 1))
|
||||||
|
|
||||||
need_show_all_link = cl.can_show_all and not cl.show_all and cl.multi_page
|
need_show_all_link = cl.can_show_all and not cl.show_all and cl.multi_page
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -77,9 +77,9 @@ class ChangeList:
|
||||||
messages.error(request, ', '.join(error))
|
messages.error(request, ', '.join(error))
|
||||||
self.query = _search_form.cleaned_data.get(SEARCH_VAR) or ''
|
self.query = _search_form.cleaned_data.get(SEARCH_VAR) or ''
|
||||||
try:
|
try:
|
||||||
self.page_num = int(request.GET.get(PAGE_VAR, 0))
|
self.page_num = int(request.GET.get(PAGE_VAR, 1))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.page_num = 0
|
self.page_num = 1
|
||||||
self.show_all = ALL_VAR in request.GET
|
self.show_all = ALL_VAR in request.GET
|
||||||
self.is_popup = IS_POPUP_VAR in request.GET
|
self.is_popup = IS_POPUP_VAR in request.GET
|
||||||
to_field = request.GET.get(TO_FIELD_VAR)
|
to_field = request.GET.get(TO_FIELD_VAR)
|
||||||
|
@ -247,7 +247,7 @@ class ChangeList:
|
||||||
result_list = self.queryset._clone()
|
result_list = self.queryset._clone()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
result_list = paginator.page(self.page_num + 1).object_list
|
result_list = paginator.page(self.page_num).object_list
|
||||||
except InvalidPage:
|
except InvalidPage:
|
||||||
raise IncorrectLookupParameters
|
raise IncorrectLookupParameters
|
||||||
|
|
||||||
|
|
|
@ -380,6 +380,12 @@ backends.
|
||||||
unique constraints (:attr:`.UniqueConstraint.include`), set
|
unique constraints (:attr:`.UniqueConstraint.include`), set
|
||||||
``DatabaseFeatures.supports_covering_indexes`` to ``True``.
|
``DatabaseFeatures.supports_covering_indexes`` to ``True``.
|
||||||
|
|
||||||
|
:mod:`django.contrib.admin`
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Pagination links in the admin are now 1-indexed instead of 0-indexed, i.e.
|
||||||
|
the query string for the first page is ``?p=1`` instead of ``?p=0``.
|
||||||
|
|
||||||
:mod:`django.contrib.gis`
|
:mod:`django.contrib.gis`
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@ class ChangeListTests(TestCase):
|
||||||
Regression test for #14312: list_editable with pagination
|
Regression test for #14312: list_editable with pagination
|
||||||
"""
|
"""
|
||||||
new_parent = Parent.objects.create(name='parent')
|
new_parent = Parent.objects.create(name='parent')
|
||||||
for i in range(200):
|
for i in range(1, 201):
|
||||||
Child.objects.create(name='name %s' % i, parent=new_parent)
|
Child.objects.create(name='name %s' % i, parent=new_parent)
|
||||||
request = self.factory.get('/child/', data={'p': -1}) # Anything outside range
|
request = self.factory.get('/child/', data={'p': -1}) # Anything outside range
|
||||||
request.user = self.superuser
|
request.user = self.superuser
|
||||||
|
@ -274,7 +274,7 @@ class ChangeListTests(TestCase):
|
||||||
|
|
||||||
def test_custom_paginator(self):
|
def test_custom_paginator(self):
|
||||||
new_parent = Parent.objects.create(name='parent')
|
new_parent = Parent.objects.create(name='parent')
|
||||||
for i in range(200):
|
for i in range(1, 201):
|
||||||
Child.objects.create(name='name %s' % i, parent=new_parent)
|
Child.objects.create(name='name %s' % i, parent=new_parent)
|
||||||
|
|
||||||
request = self.factory.get('/child/')
|
request = self.factory.get('/child/')
|
||||||
|
@ -576,7 +576,7 @@ class ChangeListTests(TestCase):
|
||||||
use queryset set by modeladmin.
|
use queryset set by modeladmin.
|
||||||
"""
|
"""
|
||||||
parent = Parent.objects.create(name='anything')
|
parent = Parent.objects.create(name='anything')
|
||||||
for i in range(30):
|
for i in range(1, 31):
|
||||||
Child.objects.create(name='name %s' % i, parent=parent)
|
Child.objects.create(name='name %s' % i, parent=parent)
|
||||||
Child.objects.create(name='filtered %s' % i, parent=parent)
|
Child.objects.create(name='filtered %s' % i, parent=parent)
|
||||||
|
|
||||||
|
@ -652,7 +652,7 @@ class ChangeListTests(TestCase):
|
||||||
|
|
||||||
def test_show_all(self):
|
def test_show_all(self):
|
||||||
parent = Parent.objects.create(name='anything')
|
parent = Parent.objects.create(name='anything')
|
||||||
for i in range(30):
|
for i in range(1, 31):
|
||||||
Child.objects.create(name='name %s' % i, parent=parent)
|
Child.objects.create(name='name %s' % i, parent=parent)
|
||||||
Child.objects.create(name='filtered %s' % i, parent=parent)
|
Child.objects.create(name='filtered %s' % i, parent=parent)
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ class ChangeListTests(TestCase):
|
||||||
custom_site.register(UnorderedObject, UnorderedObjectAdmin)
|
custom_site.register(UnorderedObject, UnorderedObjectAdmin)
|
||||||
model_admin = UnorderedObjectAdmin(UnorderedObject, custom_site)
|
model_admin = UnorderedObjectAdmin(UnorderedObject, custom_site)
|
||||||
counter = 0 if ascending else 51
|
counter = 0 if ascending else 51
|
||||||
for page in range(0, 5):
|
for page in range(1, 6):
|
||||||
request = self._mocked_authenticated_request('/unorderedobject/?p=%s' % page, superuser)
|
request = self._mocked_authenticated_request('/unorderedobject/?p=%s' % page, superuser)
|
||||||
response = model_admin.changelist_view(request)
|
response = model_admin.changelist_view(request)
|
||||||
for result in response.context_data['cl'].result_list:
|
for result in response.context_data['cl'].result_list:
|
||||||
|
@ -1013,7 +1013,7 @@ class ChangeListTests(TestCase):
|
||||||
custom_site.register(OrderedObject, OrderedObjectAdmin)
|
custom_site.register(OrderedObject, OrderedObjectAdmin)
|
||||||
model_admin = OrderedObjectAdmin(OrderedObject, custom_site)
|
model_admin = OrderedObjectAdmin(OrderedObject, custom_site)
|
||||||
counter = 0 if ascending else 51
|
counter = 0 if ascending else 51
|
||||||
for page in range(0, 5):
|
for page in range(1, 6):
|
||||||
request = self._mocked_authenticated_request('/orderedobject/?p=%s' % page, superuser)
|
request = self._mocked_authenticated_request('/orderedobject/?p=%s' % page, superuser)
|
||||||
response = model_admin.changelist_view(request)
|
response = model_admin.changelist_view(request)
|
||||||
for result in response.context_data['cl'].result_list:
|
for result in response.context_data['cl'].result_list:
|
||||||
|
@ -1245,12 +1245,12 @@ class ChangeListTests(TestCase):
|
||||||
per_page = cl.list_per_page = 10
|
per_page = cl.list_per_page = 10
|
||||||
|
|
||||||
for page_num, objects_count, expected_page_range in [
|
for page_num, objects_count, expected_page_range in [
|
||||||
(0, per_page, []),
|
(1, per_page, []),
|
||||||
(0, per_page * 2, list(range(2))),
|
(1, per_page * 2, list(range(1, 3))),
|
||||||
(5, per_page * 11, list(range(11))),
|
(6, per_page * 11, list(range(1, 12))),
|
||||||
(5, per_page * 12, [0, 1, 2, 3, 4, 5, 6, 7, 8, '.', 10, 11]),
|
(6, per_page * 12, [1, 2, 3, 4, 5, 6, 7, 8, 9, '.', 11, 12]),
|
||||||
(6, per_page * 12, [0, 1, '.', 3, 4, 5, 6, 7, 8, 9, 10, 11]),
|
(7, per_page * 12, [1, 2, '.', 4, 5, 6, 7, 8, 9, 10, 11, 12]),
|
||||||
(6, per_page * 13, [0, 1, '.', 3, 4, 5, 6, 7, 8, 9, '.', 11, 12]),
|
(7, per_page * 13, [1, 2, '.', 4, 5, 6, 7, 8, 9, 10, '.', 12, 13]),
|
||||||
]:
|
]:
|
||||||
# assuming we have exactly `objects_count` objects
|
# assuming we have exactly `objects_count` objects
|
||||||
Group.objects.all().delete()
|
Group.objects.all().delete()
|
||||||
|
|
|
@ -3292,7 +3292,7 @@ class AdminViewListEditable(TestCase):
|
||||||
self.assertContains(response, 'Unordered object #3')
|
self.assertContains(response, 'Unordered object #3')
|
||||||
self.assertContains(response, 'Unordered object #2')
|
self.assertContains(response, 'Unordered object #2')
|
||||||
self.assertNotContains(response, 'Unordered object #1')
|
self.assertNotContains(response, 'Unordered object #1')
|
||||||
response = self.client.get(reverse('admin:admin_views_unorderedobject_changelist') + '?p=1')
|
response = self.client.get(reverse('admin:admin_views_unorderedobject_changelist') + '?p=2')
|
||||||
self.assertNotContains(response, 'Unordered object #3')
|
self.assertNotContains(response, 'Unordered object #3')
|
||||||
self.assertNotContains(response, 'Unordered object #2')
|
self.assertNotContains(response, 'Unordered object #2')
|
||||||
self.assertContains(response, 'Unordered object #1')
|
self.assertContains(response, 'Unordered object #1')
|
||||||
|
|
Loading…
Reference in New Issue