“Implémentez facilement la consultation de données avec Django ListView et DetailView,
maximisez votre productivité de développement !”

Dans l'article précédent, nous avons découvert la classe de vue de base de Django et la FormView, passons maintenant à des vues génériques plus spécifiques.
ListView et DetailView sont particulièrement des classes spécialisées dans l'affichage des données, permettant de créer rapidement des pages de liste et des pages détaillées avec seulement quelques configurations simples.


1. Qu'est-ce que ListView et DetailView ?

  1. ListView

    • Fournit la fonctionnalité d'affichage de plusieurs objets d'un modèle sous forme de liste.

    • Facile à appliquer des fonctionnalités de pagination, de tri, de recherche, ce qui en fait un atout dans la plupart des “pages de liste”.

  2. DetailView

    • Affiche les détails d'un objet spécifique (par exemple : article, produit, utilisateur, etc.).

    • Peut trouver l'objet via un paramètre URL ou une valeur pk (clé primaire) et le rendre simplement dans le modèle.

Ces deux classes font partie des vues génériques fournies par Django et sont des outils puissants pour implémenter rapidement le rôle “Lecture” dans le CRUD.


2. Structure de base et utilisation de ListView

Diagramme de flux de traitement ListView

2.1 Exemple de base

# views.py
from django.views.generic import ListView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'post_list.html'
    context_object_name = 'posts'  # Nom de la variable contextuelle à utiliser dans le modèle (valeur par défaut : object_list)
    # paginate_by = 10  # Nombre d'éléments à afficher par page (optionnel)

    # utiliser get_queryset lorsque des ajustements de queryset supplémentaires sont nécessaires
    def get_queryset(self):
        # Ex : Si vous souhaitez afficher uniquement les articles les plus récents ?
        return Post.objects.order_by('-created_at')
  • model: spécifie quel modèle afficher.

  • template_name: chemin du fichier modèle (valeur par défaut : <app_name>/<model_name>_list.html).

  • context_object_name: nom de l'objet contextuel à utiliser dans le modèle (valeur par défaut : object_list).

  • paginate_by: peut spécifier le nombre d'objets à afficher par page (pagination).

2.2 Lier ListView dans urls.py

# urls.py
from django.urls import path
from .views import PostListView

urlpatterns = [
    path('posts/', PostListView.as_view(), name='post_list'),
]

2.3 Exemple de modèle de base

<!-- post_list.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Liste des articles</title>
</head>
<body>
    <h1>Liste des articles</h1>
    <ul>
        {% for post in posts %}
            <li>
                <a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a>
            </li>
        {% endfor %}
    </ul>

    <!-- Lors de l'implémentation de la pagination -->
    {% if is_paginated %}
      <div>
        {% if page_obj.has_previous %}
          <a href="?page={{ page_obj.previous_page_number }}">Précédent</a>
        {% endif %}
        <span>Page {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}</span>
        {% if page_obj.has_next %}
          <a href="?page={{ page_obj.next_page_number }}">Suivant</a>
        {% endif %}
      </div>
    {% endif %}
</body>
</html>

Mots-clés clés: “Automatisation des pages de liste”, “Pagination”, “Énumération efficace des données”


3. Structure de base et utilisation de DetailView

3.1 Exemple de base

# views.py
from django.views.generic import DetailView
from .models import Post

class PostDetailView(DetailView):
    model = Post
    template_name = 'post_detail.html'
    context_object_name = 'post'  # Nom de la variable contextuelle à utiliser dans le modèle (valeur par défaut : object)

    # (optionnel) Vous pouvez surcharger pour utiliser un autre identifiant au lieu de pk avec get_slug_field
  • model: permet de consulter un seul objet d'un modèle spécifique.

  • template_name: chemin du fichier modèle (valeur par défaut : <app_name>/<model_name>_detail.html).

  • context_object_name: nom de l'objet contextuel à utiliser dans le modèle (valeur par défaut : object).

  • Si le modèle URL contient un modèle comme <int:pk>/ ou <slug:slug>/, Django trouvera automatiquement l'objet par cette valeur.

3.2 Lier DetailView dans urls.py

# urls.py
from django.urls import path
from .views import PostDetailView

urlpatterns = [
    path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'),
]

3.3 Exemple de modèle de base

<!-- post_detail.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ post.title }}</title>
</head>
<body>
    <h1>{{ post.title }}</h1>
    <p>Date de création : {{ post.created_at }}</p>
    <div>
        {{ post.content }}
    </div>
    <a href="{% url 'post_list' %}">Retour à la liste</a>
</body>
</html>

4. Extension de ListView & DetailView

4.1 get_queryset, get_context_data

get_queryset(): vous pouvez personnaliser le queryset selon vos conditions souhaitées.
Exemple : liste des articles visibles uniquement par un utilisateur spécifique, filtrage par mot-clé, tri par certains champs, etc.

def get_queryset(self):
    queryset = super().get_queryset()
    return queryset.filter(is_active=True)

get_context_data(): vous pouvez ajouter des données supplémentaires à transmettre au modèle.

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['extra_info'] = 'Informations supplémentaires'
    return context

4.2 slug, recherche personnalisée

DetailView peut utiliser slug (identifiant texte court) à la place de pk et peut être personnalisée avec slug_field, slug_url_kwarg, etc.

class PostDetailView(DetailView):
    model = Post
    slug_field = 'slug'           # Nom du champ slug dans le modèle
    slug_url_kwarg = 'slug'       # Nom du paramètre dans le modèle URL

4.3 Combinaison avec Mixin

  • LoginRequiredMixin ou PermissionRequiredMixin peuvent être utilisés pour contrôler facilement les droits d'accès aux pages de liste et détaillées.

  • Vous pouvez aussi étendre en créant un Mixin personnalisé comme SearchMixin pour gérer la logique des paramètres de requête dans plusieurs ListView.


5. Exemple concret : Mise en œuvre de la fonction de forum

En prenant comme base le modèle Post discuté précédemment, nous allons construire liste + détail en une seule fois.

# models.py
class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(unique=True)  # Exemple d'utilisation de slug

    def __str__(self):
        return self.title
# views.py
from django.views.generic import ListView, DetailView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'post_list.html'
    context_object_name = 'posts'
    paginate_by = 5  # 5 par page

    def get_queryset(self):
        # Supposons que seuls les articles actifs sont affichés
        return Post.objects.filter(is_active=True).order_by('-created_at')

class PostDetailView(DetailView):
    model = Post
    template_name = 'post_detail.html'
    context_object_name = 'post'
    slug_field = 'slug'
    slug_url_kwarg = 'slug'
# urls.py
urlpatterns = [
    path('posts/', PostListView.as_view(), name='post_list'),
    path('posts/<slug:slug>/', PostDetailView.as_view(), name='post_detail'),
]
  • Page de liste: Vous pouvez vérifier la liste en changeant le numéro de page comme /posts/?page=2.

  • Page de détail: Utilisez le chemin posts/<slug>/ pour rechercher un article spécifique et l'afficher dans le modèle.


6. Comparaison avec FBV : À quel point il est facile d'implémenter une liste / un détail ?

Catégorie FBV (vues basées sur des fonctions) ListView/DetailView (CBV)
Structure du code Écrivez chaque fonction pour liste/détail, devez implémenter pagination/tri, etc. manuellement La personnalisation facile de la liste, pagination, tri, recherche, etc. avec simplement la configuration des attributs
Lisibilité / Maintenabilité Les déclarations conditionnelles et les boucles deviennent mélangées, rendant le projet de plus en plus complexe Logique de liste/détail séparée, l'extension (surcharge de méthodes) est claire, ce qui facilite la maintenance du code
Productivité de développement (mot-clé clé) “Augmentation de la duplication de code, perte de temps” “Réduction du temps de développement, amélioration de la productivité”
Transmission de données au modèle Doit construire manuellement le dictionnaire contextuel et le transmettre à render Le contexte (object_list, object) est transmis automatiquement par défaut. Les données supplémentaires peuvent être facilement traitées dans get_context_data
Fonctionnalités avancées comme la pagination, la recherche, etc. Nécessite une logique distincte Peut être activé facilement avec les fonctionnalités et attributs intégrés

FBV vs DetailView – Consultation d'objets simplifiée


7. Conclusion et aperçu du prochain article

ListView et DetailView de Django simplifient de manière révolutionnaire la mise en œuvre de “listes de données” et “pages détaillées”.
En automatisant des fonctionnalités telles que la pagination, l'ajout de données contextuelles et la consultation d'objets basés sur des paramètres URL, cela offre de grands avantages en matière de réutilisabilité du code et de productivité de développement.

La série CBV (Vue Basée sur des Classes) continue !
Dans le prochain article, nous explorerons comment construire simplement des logiques CRUD en utilisant CreateView, UpdateView, DeleteView.


Revoir les articles précédents

  1. Série d'exploration des vues basées sur des classes (CBV) #1 - Pourquoi passer de FBV à CBV et l'attitude d'un développeur

  2. Série d'exploration des vues basées sur des classes (CBV) #2 - Comprendre la classe de base de la vue Django

  3. Série d'exploration des vues basées sur des classes (CBV) #3 - Faciliter le traitement du formulaire avec FormView


“Profitez de la consultation rapide de données, d'un développement facile et d'une productivité élevée en utilisant ListView et DetailView de Django !”