Pagination and ordering.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
26e06dfaea
commit
659577aaac
3
Makefile
3
Makefile
|
@ -11,7 +11,8 @@ run:
|
|||
${DOCKER_COMPOSE} up
|
||||
|
||||
setup_venv:
|
||||
python3.10 -m venv venv;
|
||||
rm -rf venv
|
||||
python3.11 -m venv venv;
|
||||
venv/bin/python -m pip install wheel setuptools;
|
||||
venv/bin/python -m pip install docker-compose pre-commit boto3 pip-tools;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ def get_memberships(
|
|||
|
||||
|
||||
def get_members():
|
||||
return Member.objects.all().annotate_membership()
|
||||
return Member.objects.all().annotate_membership().order_by("username")
|
||||
|
||||
|
||||
def get_member(*, member_id: int) -> Member:
|
||||
|
|
|
@ -40,6 +40,7 @@ def members_admin(request):
|
|||
|
||||
return render_list(
|
||||
request=request,
|
||||
paginate_by=20,
|
||||
objects=users,
|
||||
columns=[
|
||||
("username", _("Username")),
|
||||
|
|
|
@ -3,11 +3,19 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<h1>
|
||||
Users <small class="text-muted">{{ total_count }}</small>
|
||||
</h1>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for column in columns %}
|
||||
<th scope="col">{{ column }}</th>
|
||||
{% for column, column_label in columns %}
|
||||
<th scope="col">
|
||||
<a href="?order_by={% if order_by == column %}-{% endif %}{{ column }}">
|
||||
{{ column_label }}
|
||||
</a>
|
||||
</th>
|
||||
{% endfor %}
|
||||
{% if row_actions %}
|
||||
<th scope="col">{% trans "Actions" %}</th>
|
||||
|
@ -32,4 +40,62 @@
|
|||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% if is_paginated %}
|
||||
<nav aria-label="Page navigation example">
|
||||
<ul class="pagination justify-content-center">
|
||||
|
||||
{% if not page.has_previous %}
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link">
|
||||
{% trans "Previous" %}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page.previous_page_number }} %}">
|
||||
{% trans "Previous" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if page.number|add:'-3' > 1 %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page.number|add:'-4' }}">…</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for i in page.paginator.page_range %}
|
||||
{% if page.number == i %}
|
||||
<li class="active page-item">
|
||||
<a href="" class="page-link">{{ i }}</a>
|
||||
</li>
|
||||
{% elif i > page.number|add:'-4' and i < page.number|add:'4' %}
|
||||
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page.paginator.num_pages > page.number|add:'3' %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page.number|add:'4' }}">…</a></licl>
|
||||
{% endif %}
|
||||
|
||||
{% if not page.has_next %}
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link">
|
||||
{% trans "Next" %}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page.next_page_number }}">
|
||||
{% trans "Next" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import contextlib
|
||||
from dataclasses import dataclass
|
||||
|
||||
from django.contrib.sites.shortcuts import get_current_site as django_get_current_site
|
||||
from django.core.exceptions import FieldError
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Model
|
||||
from django.http import HttpRequest
|
||||
from django.http import HttpResponse
|
||||
|
@ -50,6 +53,7 @@ def render_list(
|
|||
columns: list[tuple[str, str]],
|
||||
row_actions: list[RowAction] = None,
|
||||
list_actions: list[tuple[str, str]] = None,
|
||||
paginate_by: int = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
Render a list of objects with a table.
|
||||
|
@ -57,6 +61,19 @@ def render_list(
|
|||
|
||||
# TODO: List actions
|
||||
|
||||
total_count = len(objects)
|
||||
|
||||
order_by = request.GET.get("order_by")
|
||||
|
||||
if order_by:
|
||||
with contextlib.suppress(FieldError):
|
||||
objects = objects.order_by(order_by)
|
||||
|
||||
if paginate_by:
|
||||
paginator = Paginator(object_list=objects, per_page=paginate_by)
|
||||
page = paginator.get_page(request.GET.get("page"))
|
||||
objects = page.object_list
|
||||
|
||||
rows = []
|
||||
for obj in objects:
|
||||
row = Row(
|
||||
|
@ -65,13 +82,19 @@ def render_list(
|
|||
)
|
||||
rows.append(row)
|
||||
|
||||
column_labels = [column[1] for column in columns]
|
||||
|
||||
context = base_view_context(request) | {
|
||||
"rows": rows,
|
||||
"columns": column_labels,
|
||||
"columns": columns,
|
||||
"row_actions": row_actions,
|
||||
"list_actions": list_actions,
|
||||
"total_count": total_count,
|
||||
"order_by": order_by,
|
||||
}
|
||||
|
||||
if paginate_by:
|
||||
context |= {
|
||||
"page": page,
|
||||
"is_paginated": True,
|
||||
}
|
||||
|
||||
return render(
|
||||
|
|
Loading…
Reference in a new issue