Menu
CoddyTech

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.

challenge icon

Aufgabe

Einfach

Zeige 5 Stellen pro Seite an.

  1. Lass JobListView in jobs/views.py 5 Stellen pro Seite anzeigen.
  2. Füge in job_list.html unterhalb der Liste <nav class="pages"> mit Links hinzu, die genau Previous und Next lauten, und dazwischen Page 1 of 3 aus page_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