Changed the links attribute of Pagination to a pseudo attribute that is calculated on request.

This commit is contained in:
依瑪貓 2020-07-07 22:49:37 +08:00
parent 19ac9d3200
commit e9509c9bac
2 changed files with 89 additions and 83 deletions

View File

@ -201,5 +201,6 @@ ORDER BY
self.kwargs["subject_code"] + "%", self.kwargs["subject_code"] + "%",
self.kwargs["subject_code"] + "%"]) self.kwargs["subject_code"] + "%"])
self.pagination = Pagination( self.pagination = Pagination(
self.request, records, self.page_no, self.page_size, True) self.request.get_full_path(), records,
self.page_no, self.page_size, True)
return self.pagination.records return self.pagination.records

View File

@ -159,6 +159,7 @@ class Pagination:
of range or is redundant. of range or is redundant.
Attributes: Attributes:
current_url (bool): The current request URL
is_reversed (bool): Whether we should display the last is_reversed (bool): Whether we should display the last
page first page first
page_size (int): The page size. page_size (int): The page size.
@ -169,18 +170,19 @@ class Pagination:
links (list[Link]): The navigation links in the pagination links (list[Link]): The navigation links in the pagination
bar. bar.
""" """
current_url = None
is_reversed = False is_reversed = False
page_size = None page_size = None
total_pages = None total_pages = None
is_paged = None is_paged = None
page_no = None page_no = None
records = None records = None
links = None
DEFAULT_PAGE_SIZE = 10 DEFAULT_PAGE_SIZE = 10
def __init__(self, request, records, page_no, def __init__(self, current_url, records, page_no,
page_size, is_reversed=False): page_size, is_reversed=False):
self.current_url = current_url
self.is_reversed = is_reversed self.is_reversed = is_reversed
self.page_size = page_size \ self.page_size = page_size \
if page_size is not None \ if page_size is not None \
@ -191,7 +193,7 @@ class Pagination:
if not self.is_paged: if not self.is_paged:
self.page_no = 1 self.page_no = 1
self.records = records self.records = records
self.links = [] self._links = []
return return
default_page = 1 if not is_reversed else self.total_pages default_page = 1 if not is_reversed else self.total_pages
if page_no == default_page: if page_no == default_page:
@ -203,99 +205,102 @@ class Pagination:
raise PageNoOutOfRangeException() raise PageNoOutOfRangeException()
start_no = self.page_size * (self.page_no - 1) start_no = self.page_size * (self.page_no - 1)
self.records = records[start_no:start_no + self.page_size] self.records = records[start_no:start_no + self.page_size]
self.create_pagination_bar(request)
def create_pagination_bar(self, request): _links = None
@property
def links(self):
"""Creates the pagination bar. """Creates the pagination bar.
Args: Args:
request (HttpRequest): The request request (HttpRequest): The request
""" """
base_url = UrlBuilder( if self._links is None:
request.get_full_path()).del_param("page") base_url = UrlBuilder(self.current_url).del_param("page")
self.links = [] self._links = []
# The previous page # The previous page
link = self.Link() link = self.Link()
link.title = pgettext("Pagination|", "Previous") link.title = pgettext("Pagination|", "Previous")
if self.page_no > 1: if self.page_no > 1:
if self.page_no - 1 == 1: if self.page_no - 1 == 1:
if not self.is_reversed: if not self.is_reversed:
link.url = str(base_url) link.url = str(base_url)
else:
link.url = str(base_url.clone().add_param(
"page", "1"))
else: else:
link.url = str(base_url.clone().add_param( link.url = str(base_url.clone().add_param(
"page", "1")) "page", str(self.page_no - 1)))
else: link.is_small_screen = True
link.url = str(base_url.clone().add_param( self._links.append(link)
"page", str(self.page_no - 1))) # The first page
link.is_small_screen = True
self.links.append(link)
# The first page
link = self.Link()
link.title = "1"
if not self.is_reversed:
link.url = str(base_url)
else:
link.url = str(base_url.clone().add_param("page", "1"))
if self.page_no == 1:
link.is_active = True
self.links.append(link)
# The previous ellipsis
if self.page_no > 4:
link = self.Link() link = self.Link()
if self.page_no > 5: link.title = "1"
link.title = pgettext("Pagination|", "...") if not self.is_reversed:
link.url = str(base_url)
else: else:
link.title = "2" link.url = str(base_url.clone().add_param("page", "1"))
link.url = str(base_url.clone().add_param( if self.page_no == 1:
"page", "2"))
self.links.append(link)
# The nearby pages
for no in range(self.page_no - 2, self.page_no + 3):
if no <= 1 or no >= self.total_pages:
continue
link = self.Link()
link.title = str(no)
link.url = str(base_url.clone().add_param(
"page", str(no)))
if no == self.page_no:
link.is_active = True link.is_active = True
self.links.append(link) self._links.append(link)
# The next ellipsis # The previous ellipsis
if self.page_no + 3 < self.total_pages: if self.page_no > 4:
link = self.Link() link = self.Link()
if self.page_no + 4 < self.total_pages: if self.page_no > 5:
link.title = pgettext("Pagination|", "...") link.title = pgettext("Pagination|", "...")
else: else:
link.title = str(self.total_pages - 1) link.title = "2"
link.url = str(base_url.clone().add_param(
"page", "2"))
self._links.append(link)
# The nearby pages
for no in range(self.page_no - 2, self.page_no + 3):
if no <= 1 or no >= self.total_pages:
continue
link = self.Link()
link.title = str(no)
link.url = str(base_url.clone().add_param( link.url = str(base_url.clone().add_param(
"page", str(self.total_pages - 1))) "page", str(no)))
self.links.append(link) if no == self.page_no:
# The last page link.is_active = True
link = self.Link() self._links.append(link)
link.title = str(self.total_pages) # The next ellipsis
if self.is_reversed: if self.page_no + 3 < self.total_pages:
link.url = str(base_url) link = self.Link()
else: if self.page_no + 4 < self.total_pages:
link.url = str(base_url.clone().add_param( link.title = pgettext("Pagination|", "...")
"page", str(self.total_pages))) else:
if self.page_no == self.total_pages: link.title = str(self.total_pages - 1)
link.is_active = True link.url = str(base_url.clone().add_param(
self.links.append(link) "page", str(self.total_pages - 1)))
# The next page self._links.append(link)
link = self.Link() # The last page
link.title = pgettext("Pagination|", "Next") link = self.Link()
if self.page_no < self.total_pages: link.title = str(self.total_pages)
if self.page_no + 1 == self.total_pages: if self.is_reversed:
if self.is_reversed: link.url = str(base_url)
link.url = str(base_url) else:
link.url = str(base_url.clone().add_param(
"page", str(self.total_pages)))
if self.page_no == self.total_pages:
link.is_active = True
self._links.append(link)
# The next page
link = self.Link()
link.title = pgettext("Pagination|", "Next")
if self.page_no < self.total_pages:
if self.page_no + 1 == self.total_pages:
if self.is_reversed:
link.url = str(base_url)
else:
link.url = str(base_url.clone().add_param(
"page", str(self.total_pages)))
else: else:
link.url = str(base_url.clone().add_param( link.url = str(base_url.clone().add_param(
"page", str(self.total_pages))) "page", str(self.page_no + 1)))
else: link.is_small_screen = True
link.url = str(base_url.clone().add_param( self._links.append(link)
"page", str(self.page_no + 1))) return self._links
link.is_small_screen = True
self.links.append(link)
class Link: class Link:
"""A navigation link in the pagination bar. """A navigation link in the pagination bar.