Dans notre précédent article, nous avons examiné pourquoi les vues basées sur les classes (CBV) de Django sont nécessaires et quels avantages elles offrent par rapport aux vues basées sur les fonctions (FBV). Dans cet article, nous allons plonger en détail dans la classe View de base de Django, qui peut être considérée comme la fondation de toutes les CBV.
“Pour bien comprendre les CBV, il est important de savoir comment fonctionne django.views.View et quelle est sa structure.”
1. Qu'est-ce que la classe View de Django ?
Toutes les vues basées sur les classes de Django héritent de la classe django.views.View
sous cette forme.
from django.views import View
class MyView(View):
def get(self, request, *args, **kwargs):
# Logique à traiter lors d'une requête GET
...
def post(self, request, *args, **kwargs):
# Logique à traiter lors d'une requête POST
...
Caractéristiques de la classe View
-
Séparation des méthodes par méthode HTTP
Lorsqu'une requête est reçue, Django appelle automatiquement la fonction correspondante à la méthode de la requête via la méthodedispatch()
, par exempleget()
,post()
,put()
,delete()
.- Évitant d'utiliser la condition « if request.method == 'GET': … else: … » comme dans FBV, la structure du code reste claire.
-
Héritage et extensibilité
En héritant de la classe View, il est possible de créer plusieurs vues enfants; ainsi, la logique commune est placée dans la classe parente et la logique spécifique dans la classe enfant, maximisant la réutilisation du code.
2. Structure de base et principes de la classe View
Exemple le plus simple
# views.py
from django.http import HttpResponse
from django.views import View
class HelloCBV(View):
def get(self, request, *args, **kwargs):
return HttpResponse("Bonjour, CBV !")
-
get()
méthode : exécutée lorsqu'une requête GET est envoyée depuis le navigateur (saisie de l'URL dans la barre d'adresse, clic sur un lien, etc.). -
HttpResponse("Bonjour, CBV !")
: crée et renvoie directement la réponse sous forme de texte.
Connexion avec urls.py
# urls.py
from django.urls import path
from .views import HelloCBV
urlpatterns = [
path('hello/', HelloCBV.as_view(), name='hello_cbv'),
]
-
La méthode
.as_view()
transforme la CBV dans un format compréhensible par Django. -
En la reliant à un modèle d'URL, la méthode
get()
deHelloCBV
sera appelée lorsqu'une requête GET sera reçue àhttp://example.com/hello/
.
3. Utilisation de la classe View et exemples pratiques
Un cas simple comme celui-ci, qui « renvoie simplement une chaîne de caractères », est rare. Dans des projets réels, on effectue souvent des réponses JSON, rendu de templates ou requêtes à la base de données. Nous allons ici examiner des exemples de réponses JSON et de rendu de templates.
3.1 Exemple de traitement de réponse JSON
# views.py
from django.http import JsonResponse
from django.views import View
class UserDataView(View):
def get(self, request, *args, **kwargs):
# Exemple : supposons que nous recevons un user_id en tant que paramètre GET
user_id = request.GET.get('user_id', None)
if not user_id:
return JsonResponse({'error': 'No user_id provided'}, status=400)
# Effectuer des requêtes DB dans la pratique
user_data = {
'id': user_id,
'name': f'User_{user_id}',
'role': 'admin'
}
return JsonResponse(user_data, status=200)
def post(self, request, *args, **kwargs):
# On peut analyser les données JSON ou formulaire du corps de la requête.
# Possibilité d’utiliser request.POST, request.body, request.FILES
new_user_data = {
'id': 123,
'name': 'NewUser',
'role': 'member'
}
return JsonResponse(new_user_data, status=201)
-
JsonResponse
: un outil pratique pour créer des réponses JSON dans Django. -
request.GET
,request.POST
: permet de récupérer les paramètres GET/POST depuis l'objet HttpRequest de Django. -
En pratique, on interconnecte avec un modèle DB ou utilise un Serializer pour traiter les données de manière plus structurée.
3.2 Exemple de rendu de template
# views.py
from django.shortcuts import render
from django.views import View
class GreetingView(View):
def get(self, request, *args, **kwargs):
context = {
'title': 'Bienvenue sur mon site',
'greeting': 'Bonjour, ceci est une GreetingView !'
}
return render(request, 'greeting.html', context)
<!-- templates/greeting.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ greeting }}</h1>
</body>
</html>
-
La fonction
render()
trouve le fichier de template (greeting.html
) et renvoie le HTML rendu sous forme deHttpResponse
. -
Ainsi, le rendu de template au sein de la CBV se fait de manière simple.
4. Extensibilité et réutilisation de la classe View
Une des plus grandes raisons pour lesquelles la classe View est utile est la « réutilisation du code ». À mesure qu'un projet grandit, il devient beaucoup plus efficace de placer la logique nécessaire (par exemple, journalisation, vérification d'authentification, traitement des données communes, etc.) dans la classe parente et d'hériter à partir de la classe enfant.
4.1 Placer la logique commune dans la classe parente
# views.py
from django.http import JsonResponse
from django.views import View
class BaseLoggingView(View):
def dispatch(self, request, *args, **kwargs):
# Exécute une logique commune pour toutes les requêtes (GET/POST, etc.)
print(f"[Log] {request.method} request at {request.path}")
return super().dispatch(request, *args, **kwargs)
class ChildLoggingView(BaseLoggingView):
def get(self, request, *args, **kwargs):
data = {'message': 'GET response from child'}
return JsonResponse(data)
def post(self, request, *args, **kwargs):
data = {'message': 'POST response from child'}
return JsonResponse(data)
-
La méthode
dispatch()
: un élément clé qui permet de contrôler l'exécution de la logique de vue avant et après son exécution. -
Dans cet exemple, nous enregistrons un log pour chaque requête avant d'appeler effectivement
get()
,post()
, etc., viasuper().dispatch()
.
4.2 Ajout de fonctionnalités via des Mixins
Dans Django, il est courant d'utiliser la technique des Mixins pour « n'ajouter que les fonctionnalités spécifiques ». Par exemple, utiliser LoginRequiredMixin (pour vérifier si l'utilisateur est connecté) ou PermissionRequiredMixin (pour vérifier les permissions) dans les CBV.
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
from django.http import JsonResponse
class SecuredView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
return JsonResponse({'message': 'Vous êtes authentifié.'})
- Mixin sera abordé plus en détail lorsque nous parlerons des vues génériques ou de la gestion des permissions, donc il est suffisant de comprendre que les fonctionnalités peuvent s'accumuler de cette manière.
5. Comparaison rapide avec FBV
Catégorie | FBV (Vue basée sur les fonctions) | CBV (Vue basée sur les classes) |
---|---|---|
Forme d’écriture | Rédigée sous forme de fonction | Rédigée sous forme de classe & méthode |
Traitement des méthodes HTTP | if request.method == 'GET': ... else: ... |
get() , post() , séparées par méthode |
Risques de duplication de code | Difficile d’éviter la duplication lorsque la logique devient complexe | Réutilisation de la logique commune possible à travers l'héritage et les Mixins |
Extensibilité | Les logiques communes sont souvent mêlées dans une fonction | Structure d’héritage de classe adaptée aux exigences complexes |
Lisibilité | Avantageuse pour des prototypes simples | Plus adaptée au maintien d'une structure claire à mesure que la taille croît |
-
Les FBV se prêtent bien à des fonctionnalités simples ou de petite taille, tandis que les CBV sont favorables à l'extensibilité et à la maintenance.
-
Les CBV sont particulièrement efficaces pour des projets en équipe ou de grande envergure.
6. Approfondissons un peu : dispatch()
et paramètres d’URL
6.1 Raisons de surcharger dispatch()
-
Pré-traitement et post-traitement communs : On peut gérer des logiques comme vérifier la connexion à la base de données, vérifier les permissions ou enregistrer des logs chaque fois qu'une requête arrive.
-
Mapping des méthodes : Utilise
request.method.lower()
en interne pour appeler les méthodesget()
,post()
, etc. Si on souhaite traiter des méthodes commePATCH
de façon personnalisée, il faut surchargerdispatch()
.
class CustomDispatchView(View):
def dispatch(self, request, *args, **kwargs):
print("Logique de prétraitement personnalisée ici.")
response = super().dispatch(request, *args, **kwargs)
print("Logique de post-traitement personnalisée ici.")
return response
6.2 Recevoir des paramètres d’URL
Si vous avez spécifié un paramètre de chemin tel que <int:user_id>/
dans urls.py
, vous pouvez recevoir des valeurs dans les méthodes get()
et post()
de la CBV via kwargs
.
# urls.py
urlpatterns = [
path('user/<int:user_id>/', UserDetailView.as_view(), name='user_detail'),
]
# views.py
class UserDetailView(View):
def get(self, request, *args, **kwargs):
user_id = kwargs.get('user_id')
# Recherche dans la base de données avec user_id
return HttpResponse(f"User ID: {user_id}")
- Tout comme avec FBV, on peut extraires des paramètres d'URL depuis
kwargs
.
7. Un exemple plus riche : exemple de forum simple
Pour ceux qui souhaitent utiliser la classe View de manière plus pratique, prenons un exemple simple de création d'une liste et d'une page de détails pour un forum. (Dans le prochain article, nous traiterons des vues génériques qui simplifient la mise en œuvre des opérations CRUD, mais ici nous montrerons que cela peut aussi se faire simplement avec la classe View de base.)
# models.py - Modèle d'exemple
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# views.py
from django.views import View
from django.shortcuts import render, get_object_or_404
from .models import Post
# Afficher la liste des articles
class PostListView(View):
def get(self, request, *args, **kwargs):
posts = Post.objects.order_by('-created_at')
context = {'posts': posts}
return render(request, 'post_list.html', context)
# Afficher les détails des articles
class PostDetailView(View):
def get(self, request, *args, **kwargs):
post_id = kwargs.get('pk')
post = get_object_or_404(Post, pk=post_id)
context = {'post': post}
return render(request, 'post_detail.html', context)
<!-- 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.id %}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
</body>
</html>
<!-- post_detail.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<p>Date de création : {{ post.created_at }}</p>
</body>
</html>
# urls.py
from django.urls import path
from .views import PostListView, PostDetailView
urlpatterns = [
path('posts/', PostListView.as_view(), name='post_list'),
path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'),
]
-
PostListView
: Lors d'une requête GET, cette vue récupère tous les articles et les transmet au template (post_list.html
). -
PostDetailView
: Trouve un article spécifique avec le paramètre d'URLpk
et le transmet au template (post_detail.html
). -
Ainsi, même avec la classe View de base, nous pouvons facilement construire des listes et des pages de détails.
Cela dit, pour composer l'ensemble des opérations CRUD, il faut également des logiques de création, mise à jour et suppression. Ce qui facilite cela, ce sont les vues génériques proposées par Django, dont nous traiterons en détail dans le prochain article !
8. Conclusion et aperçu du prochain article
Voilà un aperçu de la façon dont la classe View de base de Django fonctionne et comment elle peut être utilisée en pratique. Pour résumer les points clés :
-
Hérite de django.views.View, et surcharge les méthodes
get()
/post()
/dispatch()
pour répondre aux requêtes HTTP. -
En plaçant la logique commune dans la classe parente et en réécrivant les parties nécessaires dans les vues enfants, nous pouvons maximiser la réutilisation du code.
-
Permet de créer facilement une logique de vue dans divers scénarios comme le rendu de templates, la réponse JSON, ou les requêtes DB.
-
Comme l'exemple pratique (une simple plateforme de forum), il est tout à fait possible de créer un projet avec seulement la classe View de base.
Mais pour traiter les opérations CRUD de manière plus simple, apprendre les vues génériques proposées par Django sera beaucoup plus pratique.
Dans le prochain article, nous traiterons en profondeur la classe FormView, qui simplifie le processus de « réception des saisies utilisateur, validation, affichage des messages d'erreur et redirection en cas de succès ». Vous pourrez ainsi voir comment automatiser ce processus.
La série CBV continue !
- Partie 3 : “Faciliter le traitement de formulaire avec FormView”
- Partie 4 : “Comment utiliser ListView & DetailView”
- Partie 5 : “Implémenter CRUD avec CreateView, UpdateView, DeleteView”
- … (et la suite)
Voir l'article précédent
Documents supplémentaires à consulter
-
Documentation officielle de Django : Vues basées sur les classes
-
Django Community – Vous pouvez trouver divers exemples dans la communauté Django.
J'espère que cet article a éclairé vos questions concernant la structure et l'utilisation des classes View de base. Dans le prochain article, nous allons explorer comment la FormView facilite le traitement des formulaires, y compris « rédaction → validation → traitement des erreurs → redirection en cas de succès ».
“Les classes View de Django ne se contentent pas de diviser le code selon les méthodes HTTP, elles constituent un outil puissant pouvant révolutionner l'extensibilité et la maintenance dans des projets à grande échelle.”
Continuons à explorer les CBV pour un développement Django plus productif !
Aucun commentaire.