Menu
CoddyTech

Paginierung

Teil des Abschnitts Klassenbasierte Views der Django-Journey von Coddy. Lektion 8 von 18.

Die Job-Seite zeigt alle Jobs auf einmal an, und tausend würden nicht auf die Seite passen. Paginierung teilt eine Liste in Seiten mit Links zwischen ihnen auf. Eine ListView übernimmt die Aufteilung mit einem Attribut, paginate_by, der Anzahl der Zeilen pro Seite.

Mit paginate_by = 20 bei einer Rezeptliste zeigt /recipes/ die ersten 20 an, /recipes/?page=2 die nächsten 20, und eine Seite hinter dem Ende liefert einen 404-Fehler. Die Liste im Template enthält nur die Zeilen dieser Seite, und das Template erhält außerdem is_paginated und page_obj, die aktuelle Seite.

Die Links schreibst du selbst. page_obj kennt number, paginator.num_pages, has_next, next_page_number, has_previous und previous_page_number:

{% if page_obj.has_next %}
  <a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}

Behalte die Prüfung um jeden Link bei: Auf der letzten Seite löst next_page_number einen Fehler aus, der die Seite zum Absturz bringt.

challenge icon

Aufgabe

Einfach

Zeige 5 Stellenangebote pro Seite:

  • In JobListView 5 Einträge pro Seite.
  • In job_list.html unter der Liste ein <nav class="pages"> mit einem Link Previous, dem Text Page 1 of 3 (tatsächliche Zahlen) und einem Link Next. Jeder Link wird nur angezeigt, wenn die entsprechende Seite existiert.

Drücke auf Run, öffne /jobs/ und drücke auf Next.

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