Pagination

This commit is contained in:
Eden Kirin
2024-04-12 20:50:47 +02:00
parent d3471d54ea
commit 33ae8fe124
3 changed files with 69 additions and 64 deletions

View File

@ -0,0 +1,53 @@
{% macro pagination(page) %}
{% macro render_link(title, page_number) %}
<a
class="page-link"
href="#"
hx-get="{{ url("filter-list-filter") }}"
hx-trigger="click"
hx-target="#filter-list-container"
hx-include="[name='zip'],[name='area'],[name='county']"
hx-vals='{"page": "{{ page_number }}"}'
>
{{ title }}
</a>
{% endmacro %}
{% if page.has_other_pages() %}
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if page.has_previous() %}
<li class="page-item">
{{ render_link(title="Previous", page_number=page.number - 1) }}
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">Previous</a>
</li>
{% endif %}
{% for p in page.paginator.get_elided_page_range(page.number, on_each_side=2, on_ends=3) %}
{% if p != page.paginator.ELLIPSIS %}
<li class="page-item {% if page.number == p %}active{% endif %}">
{{ render_link(title=p, page_number=p) }}
</li>
{% else %}
<li class="page-item">
<span class="page-link border-top-0 border-bottom-0">{{ page.paginator.ELLIPSIS }}</span>
</li>
{% endif %}
{% endfor %}
{% if page.has_next() %}
<li class="page-item">
{{ render_link(title="Next", page_number=page.number + 1) }}
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">Next</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endmacro %}

View File

@ -1,3 +1,5 @@
{% from "main/components/pagination.html" import pagination %}
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
@ -8,7 +10,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for area in areas %} {% for area in page.object_list %}
<tr> <tr>
<td>{{ area.post_office.zip }}</td> <td>{{ area.post_office.zip }}</td>
<td>{{ area.post_office.name }}</td> <td>{{ area.post_office.name }}</td>
@ -20,34 +22,4 @@
</table> </table>
{% if pagination.page_count > 1 %} {{ pagination(page) }}
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if pagination.prev_page != None %}
<li class="page-item">
<a class="page-link" href="#">Previous</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">Previous</a>
</li>
{% endif %}
{% for p in range(1, pagination.page_count) %}
<li class="page-item {% if pagination.page == p %}active{% endif %}">
<a class="page-link" href="#">{{ p }}</a>
</li>
{% endfor %}
{% if pagination.prev_page != None %}
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">Next</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass from typing import Any
from typing import Any, Tuple
from django.db.models import Model, Q, QuerySet from django.core.paginator import Page, Paginator
from django.db.models import Q, QuerySet
from project.main.models import Area, County from project.main.models import Area, County
from project.main.views.demo_view_base import DemoViewBase from project.main.views.demo_view_base import DemoViewBase
@ -13,34 +13,16 @@ def get_all_counties() -> QuerySet[County]:
return County.objects.all() return County.objects.all()
@dataclass
class Pagination:
page: int
page_size: int
page_count: int
prev_page: int
next_page: int
class FilterListViewBase(DemoViewBase): class FilterListViewBase(DemoViewBase):
def paginate(self, qs: QuerySet[Area]) -> Tuple[QuerySet[Area], Pagination]: def paginate(self, qs: QuerySet[Area]) -> Page:
page = int(self.request.GET.get("page", 1)) page = int(self.request.GET.get("page", 1))
page_size = int(self.request.GET.get("page_size", PAGE_SIZE)) page_size = int(self.request.GET.get("page_size", PAGE_SIZE))
start_offs = (page - 1) * page_size paginator = Paginator(
end_offs = start_offs + page_size object_list=qs,
per_page=page_size,
page_count = int(qs.count() / page_size)
pagination = Pagination(
page=page,
page_size=page_size,
page_count=page_count,
prev_page=page - 1 if page > 1 else None,
next_page=page + 1 if page < page_count else None,
) )
return paginator.get_page(page)
return qs[start_offs:end_offs], pagination
class FilterListView(FilterListViewBase): class FilterListView(FilterListViewBase):
@ -51,14 +33,13 @@ class FilterListView(FilterListViewBase):
def get_context_data(self, **kwargs) -> dict[str, Any]: def get_context_data(self, **kwargs) -> dict[str, Any]:
context_data = super().get_context_data(**kwargs) context_data = super().get_context_data(**kwargs)
qs, pagination = self.paginate( page = self.paginate(
qs=Area.objects.select_related("county", "post_office").all(), qs=Area.objects.select_related("county", "post_office").all(),
) )
context_data.update( context_data.update(
{ {
"areas": qs, "page": page,
"counties": get_all_counties(), "counties": get_all_counties(),
"pagination": pagination,
} }
) )
return context_data return context_data
@ -82,15 +63,14 @@ class FilterListFilterView(FilterListViewBase):
if county: if county:
q &= Q(county_id=county) q &= Q(county_id=county)
qs, pagination = self.paginate( page = self.paginate(
qs=Area.objects.select_related("county", "post_office").filter(q), qs=Area.objects.select_related("county", "post_office").filter(q),
) )
context_data.update( context_data.update(
{ {
"areas": qs, "page": page,
"counties": get_all_counties(), "counties": get_all_counties(),
"pagination": pagination,
} }
) )
return context_data return context_data