Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(table_page_range): append ellipsis for LazyPaginator if not on last page #707

Merged
merged 1 commit into from
Oct 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions django_tables2/paginators.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class UserListView(SingleTableView):

def __init__(self, object_list, per_page, look_ahead=None, **kwargs):
self._num_pages = None
self._final_num_pages = None
if look_ahead is not None:
self.look_ahead = look_ahead

Expand Down Expand Up @@ -91,8 +92,13 @@ def page(self, number):
else:
# This is the last page.
self._num_pages = number
# For rendering purposes in `table_page_range`, we have to remember the final count
self._final_num_pages = number
return Page(objects, number, self)

def is_last_page(self, number):
return number == self._final_num_pages

def _get_count(self):
raise NotImplementedError

Expand Down
3 changes: 3 additions & 0 deletions django_tables2/templatetags/django_tables2.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.utils.http import urlencode

import django_tables2 as tables
from django_tables2.paginators import LazyPaginator
from django_tables2.utils import AttributeDict

register = template.Library()
Expand Down Expand Up @@ -267,6 +268,8 @@ def table_page_range(page, paginator):
ret = [1, "..."] + list(ret)[2:]
if num_pages not in ret:
ret = list(ret)[:-2] + ["...", num_pages]
if isinstance(paginator, LazyPaginator) and not paginator.is_last_page(page.number):
ret.append("...")
return ret


Expand Down
7 changes: 4 additions & 3 deletions docs/pages/pagination.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ set `SingleTableView.table_pagination = False`
Lazy pagination
~~~~~~~~~~~~~~~

The default `~django.core.paginators.Paginator` want to count the number of items,
The default `~django.core.paginators.Paginator` wants to count the number of items,
which might be an expensive operation for large QuerySets.
In those cases, you can use `.LazyPaginator`, which does not perform a count,
but also does not know what the total amount of pages will be.
but also does not know what the total amount of pages will be, until you've hit
the last page.

The `.LazyPaginator` does this by fetching `n + 1` records where the number of records
per page is `n`. If it receives `n` or less records, it knows it is on the last page,
preventing rendering of the 'next' button.
preventing rendering of the 'next' button and further "..." ellipsis.
Usage with `SingleTableView`::

class UserListView(SingleTableView):
Expand Down
17 changes: 15 additions & 2 deletions tests/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,23 @@ def test_table_page_range_num_pages_equals_page_range_plus_one(self):
table_page_range(paginator.page(7), paginator), [1, "...", 4, 5, 6, 7, 8, 9, 10, 11]
)

def test_table_page_range_lazy(self):
def test_table_page_range_lazy_beginning(self):
paginator = LazyPaginator(range(1, 1000), 10)

self.assertEqual(table_page_range(paginator.page(1), paginator), range(1, 3))

def test_table_page_range_lazy_middle(self):
paginator = LazyPaginator(range(1, 1000), 10)

self.assertEqual(
table_page_range(paginator.page(10), paginator), [1, "...", 4, 5, 6, 7, 8, 9, 10, 11]
table_page_range(paginator.page(10), paginator),
[1, "...", 4, 5, 6, 7, 8, 9, 10, 11, "..."],
)

def test_table_page_range_lazy_last_page(self):
paginator = LazyPaginator(range(1, 1000), 10)

self.assertEqual(
table_page_range(paginator.page(100), paginator),
[1, "...", 93, 94, 95, 96, 97, 98, 99, 100],
)