Pagination
Fait partie de la section Vues basées sur des classes du Journey Django de Coddy. Leçon 8 sur 18.
La page des offres d’emploi affiche tous les emplois à la fois, et elle ne pourrait pas en contenir un millier. La pagination répartit une liste sur plusieurs pages reliées entre elles. Une ListView effectue cette répartition à l’aide d’un seul attribut, paginate_by, qui indique le nombre de lignes par page.
Avec paginate_by = 20 sur une liste de recettes, /recipes/ affiche les 20 premières, /recipes/?page=2 les 20 suivantes, et une page au-delà de la dernière, ou une page dont le numéro n’est pas un nombre, renvoie une réponse 404. La liste du modèle ne contient que les lignes de la page actuelle, et le modèle reçoit également is_paginated et page_obj, la page actuelle.
C’est à toi d’écrire les liens à partir de page_obj : number correspond à cette page et paginator.num_pages au nombre de pages. has_next et has_previous valent True lorsqu’il y a une page après ou avant celle-ci, et next_page_number et previous_page_number donnent son numéro :
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}Garde la condition autour de chaque lien : sur la dernière page, next_page_number déclenche une erreur qui fait planter la page.
Défi
FacileAfficher 5 offres par page.
- Dans
jobs/views.py, configurezJobListViewpour afficher 5 offres par page. - Dans
job_list.html, sous la liste, ajoutez<nav class="pages">avec des liens dont le texte est exactementPreviousetNext, et entre les deuxPage 1 of 3provenant depage_obj. Affichez chaque lien uniquement si sa page existe, sinon la page plante.
Ouvrez /jobs/ et cliquez sur Next : vous voyez Page 2 of 3.
Essayez vous-même
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
Toutes les leçons de Vues basées sur des classes
Entraînez-vous par vous-même : Playground Django