• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 12/12/19

Affichez une liste de résultats sur plusieurs pages

Log in or subscribe for free to enjoy all this course has to offer!

 

Dans ce chapitre vous ajouterez une fonctionnalité intéressante : la pagination !

De quoi s'agit-il ?

La pagination permet d'afficher une petite partie d'une liste dans une page. Par exemple, imaginons que notre disquaire ait 120 albums. Il ne veut pas que tous s'affichent sur une seule page ! A l'inverse, il souhaite que la liste d'albums s'affiche sur plusieurs pages et qu'une navigation, située en bas de page, permette d'afficher les suivants. Il y aura donc 3 pages en tout.

La pagination dans les vues

Module Paginator

Là encore, Django nous est d'un fier secours ! Nul besoin d'installer une librairie externe : utilisez Paginator !

Commencez par l'importer :

views.py

from django.core.paginator import Paginator

Puis créez une instance de la classe Paginator avec les paramètres suivants :

  • le premier paramètre est la liste d'objets à répartir entre plusieurs pages.

  • le second paramètre est le nombre d'items par page.

views.py

def listing(request):
    albums_list = Album.objects.filter(available=True)
    # Slice pages
    paginator = Paginator(albums_list, 9)
    # Get current page number
    page = request.GET.get('page')
    # Return only this page albums and not others
    albums = paginator.page(page)
    context = {
        'albums': albums
    }
    return render(request, 'store/listing.html', context)

Ainsi, si albums_list contient 26 items, Paginator génère trois groupes : les deux premiers composés de 12 albums chacun et le dernier des deux restants ! Puis il récupère dans l'URL le numéro de la page actuelle à travers le paramètre page. Enfin, il renvoie un groupe d'albums grâce à la méthode page() qui prend en paramètre la page actuelle.

Avant d'essayer, ajoutez quelques exceptions.

Exceptions

Le numéro de page étant dans l'URL, des erreurs sont facilement arrivées ! Ajoutez ces quelques lignes pour renvoyer un contenu même si le numéro de la page est erroné.

views.py

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

...

def listing(request):
    albums_list = Album.objects.filter(available=True)
    paginator = Paginator(albums_list, 9)
    page = request.GET.get('page')
    try:
        albums = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        albums = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        albums = paginator.page(paginator.num_pages)
    context = {
        'albums': albums
    }
    return render(request, 'store/listing.html', context)

Il est temps de tester ! Ouvrez la page "Tous nos disques" à l'adresse http://127.0.0.1:8000/store/. Vous devriez voir apparaître les neuf premiers albums de votre collection ! Bravo !

La pagination dans un gabarit

Néanmoins, il manque les liens en bas de page qui permettent de voir les albums suivants. Ajoutez-les tout de suite :

list.html

  <div class="clearfix"></div>
  <nav aria-label="...">
    <ul class="pager">
      {% if albums.has_previous %}
          <li><a href="?page={{ albums.previous_page_number }}">Précédent</a></li>
      {% endif %}
      {% if albums.has_next %}
          <li><a href="?page={{ albums.next_page_number }}">Suivant</a></li>
      {% endif %}
    </ul>
  </nav>

Relancez la page : les boutons apparaissent !

Néanmoins, une erreur ne va pas tarder à pointer le bout du nez : les gabarits utilisant la liste afficheront tout de même les balises divnav et ul même si la pagination n'est pas disponible.

Réparez cette erreur en ajoutant une nouvelle variable dans la vue et une structure conditionnelle dans le gabarit :

views.py

def listing(request):
    ...
    context = {
        'albums': albums,
        'paginate': True
    }

list.html

{% if paginate %}
  <div class="clearfix"></div>
  <nav aria-label="">
    <ul class="pager">
      {% if albums.has_previous %}
          <li><a href="?page={{ albums.previous_page_number }}">Précédent</a></li>
      {% endif %}
      {% if albums.has_next %}
          <li><a href="?page={{ albums.next_page_number }}">Suivant</a></li>
      {% endif %}
    </ul>
  </nav>
{% endif %}

C'est terminé ! Vous en savez désormais bien plus sur les gabarits dans Django !

Toutefois, une fonctionnalité est encore manquante : la réservation d'un album ! Le formulaire est bel et bien présent mais il est plus proche de la coquille vide que du char de combat. Dans la prochaine partie vous découvrirez comment l'activer. C'est parti !

Code de ce chapitre

Retrouvez l'intégralité du code sur ce dépôt GitHub.

Example of certificate of achievement
Example of certificate of achievement