Skip to content
Snippets Groups Projects
Commit 8329c5a1 authored by Vaibhav Mule's avatar Vaibhav Mule
Browse files

upgrade to django tables 2

parent 6c122db3
No related branches found
No related tags found
No related merge requests found
from django.core.paginator import EmptyPage, Page, PageNotAnInteger, Paginator
from django.utils.translation import gettext as _
# https://django-tables2.readthedocs.io/en/latest/pages/api-reference.html#django_tables2.paginators.LazyPaginator
# REMOVE IN django_tables2 2.0
class LazyPaginator(Paginator):
"""
Implement lazy pagination, preventing any count() queries.
By default, for any valid page, the total number of pages for the paginator will be
- `current + 1` if the number of records fetched for the current page offset is
bigger than the number of records per page.
- `current` if the number of records fetched is less than the number of records per page.
The number of additional records fetched can be adjusted using `look_ahead`, which
defaults to 1 page. If you like to provide a little more extra information on how much
pages follow the current page, you can use a higher value.
.. note::
The number of records fetched for each page is `per_page * look_ahead + 1`, so increasing
the value for `look_ahead` makes the view a bit more expensive.
So::
paginator = LazyPaginator(range(10000), 10)
>>> paginator.page(1).object_list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> paginator.num_pages
2
>>> paginator.page(10).object_list
[91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
>>> paginator.num_pages
11
>>> paginator.page(1000).object_list
[9991, 9992, 9993, 9994, 9995, 9996, 9997, 9998, 9999]
>>> paginator.num_pages
1000
Usage with `~.SingleTableView`::
class UserListView(SingleTableView):
table_class = UserTable
table_data = User.objects.all()
pagination_class = LazyPaginator
Or with `~.RequestConfig`::
RequestConfig(paginate={"paginator_class": LazyPaginator}).configure(table)
.. versionadded :: 2.0.0
"""
look_ahead = 1
def __init__(self, object_list, per_page, look_ahead=None, **kwargs):
self._num_pages = None
if look_ahead is not None:
self.look_ahead = look_ahead
super().__init__(object_list, per_page, **kwargs)
def validate_number(self, number):
"""Validate the given 1-based page number."""
try:
if isinstance(number, float) and not number.is_integer():
raise ValueError
number = int(number)
except (TypeError, ValueError):
raise PageNotAnInteger(_("That page number is not an integer"))
if number < 1:
raise EmptyPage(_("That page number is less than 1"))
return number
def page(self, number):
number = self.validate_number(number)
bottom = (number - 1) * self.per_page
top = bottom + self.per_page
# Retrieve more objects to check if there is a next page.
look_ahead_items = (self.look_ahead - 1) * self.per_page + 1
objects = list(self.object_list[bottom: top + self.orphans + look_ahead_items])
objects_count = len(objects)
if objects_count > (self.per_page + self.orphans):
# If another page is found, increase the total number of pages.
self._num_pages = number + (objects_count // self.per_page)
# In any case, return only objects for this page.
objects = objects[: self.per_page]
elif (number != 1) and (objects_count <= self.orphans):
raise EmptyPage(_("That page contains no results"))
else:
# This is the last page.
self._num_pages = number
return Page(objects, number, self)
def _get_count(self):
return 0
count = property(_get_count)
def _get_num_pages(self):
return self._num_pages
num_pages = property(_get_num_pages)
def _get_page_range(self):
raise NotImplementedError
page_range = property(_get_page_range)
......@@ -86,7 +86,6 @@ class SubmissionsTable(tables.Table):
qs = qs.order_by(update_order, 'submit_time')
return qs, True
# For when we update to Django Tables2 2.x.
def get_column_class_names(self, classes_set, bound_column):
classes_set = super(SubmissionsTable, self).get_column_class_names(classes_set, bound_column)
classes_set.add(bound_column.name)
......@@ -309,11 +308,10 @@ class RoundsTable(tables.Table):
def order_progress(self, qs, desc):
return qs.order_by(self._field_order('progress', desc)), True
# For when we update to Django Tables2 2.x.
# def get_column_class_names(self, classes_set, bound_column):
# classes_set = super(SubmissionsTable, self).get_column_class_names(classes_set, bound_column)
# classes_set.add(bound_column.name)
# return classes_set
def get_column_class_names(self, classes_set, bound_column):
classes_set = super(RoundsTable, self).get_column_class_names(classes_set, bound_column)
classes_set.add(bound_column.name)
return classes_set
class ActiveRoundFilter(Select2MultipleChoiceFilter):
......
......@@ -22,6 +22,7 @@ from django.views.generic import (
)
from django.views.generic.detail import SingleObjectMixin
from django_filters.views import FilterView
from django_tables2.paginators import LazyPaginator
from django_tables2.views import SingleTableMixin
from wagtail.core.models import Page
......@@ -69,7 +70,6 @@ from .models import (
RoundBase,
RoundsAndLabs,
)
from .paginators import LazyPaginator
from .permissions import is_user_has_access_to_view_submission
from .tables import (
AdminSubmissionsTable,
......@@ -92,7 +92,8 @@ class BaseAdminSubmissionsTable(SingleTableMixin, FilterView):
table_class = AdminSubmissionsTable
filterset_class = SubmissionFilterAndSearch
filter_action = ''
table_pagination = {'paginator_class': LazyPaginator}
paginator_class = LazyPaginator
table_pagination = {'per_page': 25}
excluded_fields = []
......
......@@ -21,7 +21,7 @@ django-pwned-passwords==4.1.0
django-redis==4.11.0
django-referrer-policy==1.0
django-storages==1.7.1
django-tables2==1.21.2
django-tables2==2.2.1
django-tinymce4-lite==1.7.5
django-two-factor-auth==1.9.1
django-webpack-loader==0.6.0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment