Vues fondées sur les classes¶
Une vue est un exécutable acceptant une requête et renvoyant une réponse. Ce n’est pas forcément une simple fonction et Django fournit des exemples de classes qui peuvent être utilisées comme des vues. Celles-ci vous permettent de structurer vos vues et de réutiliser du code en exploitant l’héritage et les « mixins ». Il existe également des vues génériques pour certaines tâches (nous y reviendrons plus tard), mais vous pouvez tout à fait concevoir votre propre structure de vues réutilisables en fonction de votre cas d’utilisation. Pour des détails plus complets, consultez la documentation de référence des vues fondées sur les classes.
Exemples de base¶
Django fournit des classes de vues basiques qui conviennent à une large palette d’applications. Toutes ces vues héritent de la classe View
, qui gère la liaison de la vue aux URL, la distribution en fonction de la méthode HTTP et d’autres fonctionnalités de base. RedirectView
sert pour les redirections HTTP alors que TemplateView
étend la classe de base afin d’être capable d’afficher un gabarit.
Utilisation dans une configuration d’URL¶
La manière la plus directe d’utiliser des vues génériques est de les créer directement dans votre configuration d’URL. Si vous ne devez changer qu’un nombre restreint d’attributs d’une vue fondée sur une classe, vous pouvez les transmettre directement dans l’appel de méthode as_view()
:
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('about/', TemplateView.as_view(template_name="about.html")),
]
Tout paramètre transmis à as_view()
surcharge l’attribut de même nom de la classe. Dans cet exemple, nous définissons template_name
de la vue TemplateView
. Le même système de surcharge peut être utilisé pour l’attribut url
de RedirectView
.
Héritage des vues génériques¶
L’autre façon, plus puissante, d’utiliser les vues génériques est d’hériter d’une vue existante et de surcharger ses attributs (comme template_name
) ou ses méthodes (comme get_context_data
) dans votre sous-classe pour fournir d’autres valeurs ou méthodes. Considérez par exemple une vue qui ne fait qu’afficher un gabarit, about.html
. Django possède une vue générique pour faire cela, TemplateView
, on peut donc en hériter et surcharger la variable du nom du gabarit :
# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
Puis, il faut ajouter cette nouvelle vue dans la configuration d’URL. Comme TemplateView
est une classe, pas une fonction, il est nécessaire de faire correspondre l’URL avec la méthode de classe as_view()
qui constitue un point d’entrée de type fonction pour les vues fondées sur les classes :
# urls.py
from django.urls import path
from some_app.views import AboutView
urlpatterns = [
path('about/', AboutView.as_view()),
]
Pour plus d’informations sur la façon d’utiliser les vues génériques intégrées dans Django, consultez le prochain thème sur les vues génériques fondées sur les classes.
Prise en charge de méthodes HTTP alternatives¶
Supposons que quelqu’un veuille accéder à notre bibliothèque de livres par HTTP en utilisant les vues comme API. Le client de cette API se connecte de temps à autre et télécharge les données des livres publiés depuis sa dernière visite. Mais si aucune publication n’a eu lieu dans l’intervalle, ce serait une perte de temps processeur et de bande passante que de récupérer les livres de la base de données, de produire une réponse complète et de l’envoyer au client. Il pourrait être préférable d’interroger l’API au sujet de la date de publication la plus récente.
Nous faisons correspondre l’URL à la vue de la liste des livres dans la configuration d’URL :
from django.urls import path
from books.views import BookListView
urlpatterns = [
path('books/', BookListView.as_view()),
]
Et la vue :
from django.http import HttpResponse
from django.views.generic import ListView
from books.models import Book
class BookListView(ListView):
model = Book
def head(self, *args, **kwargs):
last_book = self.get_queryset().latest('publication_date')
response = HttpResponse(
# RFC 1123 date format.
headers={'Last-Modified': last_book.publication_date.strftime('%a, %d %b %Y %H:%M:%S GMT')},
)
return response
Si on accède à la vue par une requête GET
, une liste d’objets est renvoyée dans la réponse (en utilisant le gabarit book_list.html
). Mais si le client lance une requête HEAD
, le corps de la réponse sera vide et l’en-tête Last-Modified
indiquera la date de publication de livre la plus récente. Sur la base de cette information, le client peut décider de charger ou non la liste complète des objets.
Asynchronous class-based views¶
As well as the synchronous (def
) method handlers already shown, View
subclasses may define asynchronous (async def
) method handlers to leverage
asynchronous code using await
:
import asyncio
from django.http import HttpResponse
from django.views import View
class AsyncView(View):
async def get(self, request, *args, **kwargs):
# Perform io-blocking view logic using await, sleep for example.
await asyncio.sleep(1)
return HttpResponse("Hello async world!")
Within a single view-class, all user-defined method handlers must be either
synchronous, using def
, or all asynchronous, using async def
. An
ImproperlyConfigured
exception will be raised in as_view()
if def
and async def
declarations are mixed.
Django will automatically detect asynchronous views and run them in an asynchronous context. You can read more about Django’s asynchronous support, and how to best use async views, in Gestion du code asynchrone.