Paginierung
Teil des Abschnitts Klassenbasierte Views der Django-Journey von Coddy. Lektion 8 von 18.
Die Jobseite zeigt alle Jobs auf einmal, und tausend würden nicht auf die Seite passen. Die Paginierung teilt eine Liste in Seiten mit Links dazwischen auf. Eine ListView übernimmt die Aufteilung mit einem Attribut, paginate_by, der Anzahl der Zeilen pro Seite.
Bei paginate_by = 20 für eine Rezeptliste zeigt /recipes/ die ersten 20 an, /recipes/?page=2 die nächsten 20, und für eine Seite hinter dem Ende oder eine Seitenangabe, die keine Zahl ist, wird eine 404-Antwort ausgegeben. Die Liste in der Vorlage enthält nur die Zeilen dieser Seite, und die Vorlage erhält außerdem is_paginated und page_obj, die aktuelle Seite.
Die Links schreibst du selbst, ausgehend von page_obj: number ist die aktuelle Seite und paginator.num_pages die Anzahl der Seiten. has_next und has_previous sind True, wenn eine Seite nach beziehungsweise vor dieser liegt, und next_page_number und previous_page_number geben deren Nummer an:
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}Führe die Prüfung für jeden Link durch: Auf der letzten Seite löst next_page_number einen Fehler aus, der die Seite zum Absturz bringt.
Aufgabe
EinfachZeige 5 Stellen pro Seite an.
- Lass
JobListViewinjobs/views.py5 Stellen pro Seite anzeigen. - Füge in
job_list.htmlunterhalb der Liste<nav class="pages">mit Links hinzu, die genauPreviousundNextlauten, und dazwischenPage 1 of 3auspage_obj. Zeige jeden Link nur an, wenn die entsprechende Seite existiert, sonst stürzt die Seite ab.
Öffne /jobs/ und klicke auf „Weiter“: Du siehst Page 2 of 3.
Probier es selbst
from django.views.generic import DetailView, ListView, TemplateView
from .models import Job
class HomeView(TemplateView):
template_name = "jobs/home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["count"] = Job.objects.count()
context["latest"] = Job.objects.order_by("-posted").first()
return context
class AboutView(TemplateView):
template_name = "jobs/about.html"
class JobListView(ListView):
model = Job
context_object_name = "jobs"
ordering = ["-posted"]
def get_queryset(self):
jobs = super().get_queryset()
city = self.request.GET.get("city")
if city:
jobs = jobs.filter(city=city)
return jobs
class JobDetailView(DetailView):
model = Job
Alle Lektionen in Klassenbasierte Views
Übe selbstständig: Django-Playground