{"title":"Vues génériques fondées sur les classes, fournies par Django","version":"4.1","locale":"fr","docname":"topics/class-based-views/generic-display","url":"/fr/4.1/topics/class-based-views/generic-display/","canonical":"https://djangodocs.dev/fr/4.1/topics/class-based-views/generic-display/","summary":"L’écriture d’applications Web peut être une tâche monotone, car certains motifs se répètent encore et encore. Django essaie d’enlever une partie de cette monotonie…","html":"<h1>Vues génériques fondées sur les classes, fournies par Django<a class=\"heading-anchor\" href=\"#built-in-class-based-generic-views\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>L’écriture d’applications Web peut être une tâche monotone, car certains motifs se répètent encore et encore. Django essaie d’enlever une partie de cette monotonie au niveau des modèles et des gabarits, mais les développeurs Web font également face à ces répétitions au niveau des vues.</p>\n<p>Les <em>vues génériques</em> de Django ont été développées pour résoudre ce problème. Elles s’attachent à trouver des motifs ou idiomes courants dans le développement des vues et à les abstraire de façon à ce qu’on puisse rapidement écrire des vues courantes sans devoir écrire trop de code.</p>\n<p>Il est possible d’identifier certaines tâches courantes, comme l’affichage d’une liste d’objets, et d’écrire du code qui affiche une liste de <em>n’importe quel</em> objet. Puis, le modèle concerné peut être transmis comme paramètre supplémentaire dans la configuration d’URL.</p>\n<p>Django est livré avec des vues génériques pour accomplir les choses suivantes :</p>\n<ul class=\"simple\">\n<li><p>Afficher des pages de liste et de détail pour un seul type d’objet. Si nous devions créer une application pour gérer des conférences, une vue <code class=\"docutils literal notranslate\"><span class=\"pre\">TalkListView</span></code> et une vue <code class=\"docutils literal notranslate\"><span class=\"pre\">RegisteredUserListView</span></code> seraient des exemples de vues de listes. Une page d’une seule conférence pourrait être un exemple de ce que nous appelons une vue de « détail ».</p></li>\n<li><p>Présenter des objets datés dans des pages d’archive par année/mois/jour, avec les détails associés et des pages « éléments récents ».</p></li>\n<li><p>Permettre à des utilisateurs de créer, mettre à jour et supprimer des objets, avec ou sans gestion des autorisations.</p></li>\n</ul>\n<p>Considérées globalement, ces vues offrent des interfaces pour effectuer les tâches les plus courantes que rencontrent les développeurs.</p>\n<section id=\"extending-generic-views\">\n<h2>Extension des vues génériques<a class=\"heading-anchor\" href=\"#extending-generic-views\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il est indiscutable que l’utilisation des vues génériques peut considérablement accélérer le développement. Dans la plupart des projets, cependant, on atteint souvent un stade où les vue génériques ne suffisent plus. En fait, la question la plus fréquemment posée par les nouveaux développeurs Django est de savoir comment il est possible de gérer plus de variétés de situations avec les vues génériques.</p>\n<p>C’est l’une des raisons pour lesquelles les vues génériques ont été revues pour la version 1.3 ; précédemment, il s’agissait de fonctions de vue avec une très large diversité d’options. Maintenant, au lieu de transmettre une grosse partie de configuration dans la configuration d’URL, la manière recommandée d’étendre les vues génériques est d’en faire des sous-classes et de surcharger leurs attributs et méthodes.</p>\n<p>Ceci dit, les vues génériques ont leurs limites. Si vous vous retrouvez à vous battre pour implémenter vos vues comme des sous-classes de vues génériques, il se pourrait qu’il soit plus efficace d’écrire simplement le code dont vous avez besoin dans vos vues, que ce soit par des fonctions ou des classes.</p>\n<p>Vous trouverez davantage d’exemples de vues génériques dans certaines applications tierces, mais n’hésitez pas à écrire vos propres vues selon vos besoins.</p>\n</section>\n<section id=\"generic-views-of-objects\">\n<h2>Vues génériques d’objets<a class=\"heading-anchor\" href=\"#generic-views-of-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/base/#django.views.generic.base.TemplateView\" title=\"django.views.generic.base.TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> est certainement utile, mais les vues génériques de Django exposent tout leur potentiel lorsqu’il s’agit de présenter des vues de contenu de la base de données. Dans la mesure où c’est une tâche très courante, Django contient un ensemble de vues génériques intégrées pour aider à générer des vues de liste et de détail pour les objets.</p>\n<p>Commençons par examiner quelques exemples d’affichage d’une liste d’objets ou d’un objet individuel.</p>\n<p>Nous allons utiliser ces modèles :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># models.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Publisher</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    <span class=\"n\">address</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">60</span><span class=\"p\">)</span>\n    <span class=\"n\">state_province</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    <span class=\"n\">country</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">website</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">URLField</span><span class=\"p\">()</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">ordering</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;-name&quot;</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Author</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">salutation</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    <span class=\"n\">email</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">()</span>\n    <span class=\"n\">headshot</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ImageField</span><span class=\"p\">(</span><span class=\"n\">upload_to</span><span class=\"o\">=</span><span class=\"s1\">&#39;author_headshots&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">authors</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ManyToManyField</span><span class=\"p\">(</span><span class=\"s1\">&#39;Author&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">publisher</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n    <span class=\"n\">publication_date</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Nous devons maintenant définir une vue :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># views.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span>\n</code></pre></div>\n<p>Et finalement connecter cette vue à une URL :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># urls.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">PublisherListView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;publishers/&#39;</span><span class=\"p\">,</span> <span class=\"n\">PublisherListView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Voilà tout le code Python qu’il suffit d’écrire. Il faut cependant encore écrire un gabarit. Nous pourrions indiquer explicitement à la vue le gabarit à utiliser en lui ajoutant un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code>, mais en l’absence d’un gabarit explicite, Django déduit un nom de gabarit à partir du nom de l’objet. Dans ce cas, le gabarit « automatique » sera <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;books/publisher_list.html&quot;</span></code>, la partie « books » provient du nom de l’application contenant ce modèle alors que « publisher » provient du nom du modèle en minuscules.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Ainsi, lorsque (par exemple) l’option <code class=\"docutils literal notranslate\"><span class=\"pre\">APP_DIRS</span></code> d’un moteur <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> est définie à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> dans <a class=\"reference internal\" href=\"/fr/4.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TEMPLATES</span></code></a>, un emplacement de gabarit pourrait être : <code class=\"docutils literal notranslate\"><span class=\"pre\">/chemin/vers/projet/books/templates/books/publisher_list.html</span></code>.</p>\n</aside>\n<p>Ce gabarit sera rendu avec un contexte contenant une variable appelée <code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code> contenant elle-même les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code>. Un gabarit pourrait ressembler à ceci :</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">extends</span> <span class=\"s2\">&quot;base.html&quot;</span> <span class=\"cp\">%}</span>\n\n<span class=\"cp\">{%</span> <span class=\"k\">block</span> <span class=\"nv\">content</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>Publishers<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">publisher</span> <span class=\"k\">in</span> <span class=\"nv\">object_list</span> <span class=\"cp\">%}</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">publisher.name</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endblock</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Et voilà, tout est là. Toutes les fonctionnalités sympathiques des vues génériques proviennent des modifications d’attributs définis dans la vue générique. La <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/\"><span class=\"doc\">référence des vues génériques</span></a> documente en détails toutes les vues génériques et leurs options. La suite de de document s’attelle à décrire certaines manières fréquentes de personnaliser et étendre les vues génériques.</p>\n<section id=\"making-friendly-template-contexts\">\n<h3>Construction de contextes de gabarits « astucieux »<a class=\"heading-anchor\" href=\"#making-friendly-template-contexts\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous avez peut-être constaté que notre exemple de gabarit de liste d’éditeurs stocke tous les éditeurs dans une variable nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code>. Même si cela fonctionne très bien, ce n’est pas très « sympa » pour les auteurs de gabarits : ils doivent simplement savoir qu’ils manipulent ici des éditeurs.</p>\n<p>Si vous avez affaire à un objet de modèle, c’est déjà fait pour vous. Lorsque vous avez affaire à un objet ou un jeu de requête, Django est capable de renseigner le contexte en utilisant la version en minuscules du nom de la classe de modèle. Ceci s’ajoute à l’élément <code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code> par défaut, mais contient exactement les mêmes données, c’est-à-dire <code class=\"docutils literal notranslate\"><span class=\"pre\">publisher_list</span></code>.</p>\n<p>Si ce n’est toujours pas un bon nom, vous pouvez indiquer explicitement le nom de la variable de contexte. L’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">context_object_name</span></code> d’une vue générique indique le nom de variable de contexte à utiliser :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># views.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span>\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;my_favorite_publishers&#39;</span>\n</code></pre></div>\n<p>La mise à disposition d’un nom <code class=\"docutils literal notranslate\"><span class=\"pre\">context_object_name</span></code> signifiant est toujours une bonne idée. Vos collaborateurs rédacteurs de gabarits vous remercieront.</p>\n</section>\n<section id=\"adding-extra-context\">\n<span id=\"id1\"></span><h3>Ajout de contexte supplémentaire<a class=\"heading-anchor\" href=\"#adding-extra-context\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il est souvent nécessaire de compléter par quelques informations supplémentaires au-delà de ce que la vue générique fournit. Par exemple, on peut penser à afficher une liste de livres sur la page de détail des éditeurs. La vue générique <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> place l’éditeur dans le contexte, mais comment ajouter d’autres informations dans le gabarit ?</p>\n<p>La réponse consiste à créer une sous-classe de <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> et d’y placer votre propre implémentation de la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data</span></code>. L’implémentation par défaut ajoute l’objet à afficher dans le gabarit, mais en la surchargeant, vous pouvez l’enrichir :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span><span class=\"p\">,</span> <span class=\"n\">Publisher</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_context_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Call the base implementation first to get a context</span>\n        <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_context_data</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Add in a QuerySet of all the books</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;book_list&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">context</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Généralement, <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data</span></code> fusionne les données de contexte de toutes les classes parentes avec celles de la classe actuelle. Pour préserver ce comportement dans vos propres classes où vous souhaitez modifier le contexte, il faut prendre soin d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data</span></code> de la classe parente (<code class=\"docutils literal notranslate\"><span class=\"pre\">super</span></code>). Pour autant qu’il n’y ait pas deux classes essayant de modifier la même clé, le résultat sera correct. Cependant, si l’une des classes tente de surcharger une clé après qu’une classe parente l’a définie (après l’appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">super</span></code>), toute classe enfant de cette classe devra aussi définir explicitement cette clé après <code class=\"docutils literal notranslate\"><span class=\"pre\">super</span></code> pour être certain de surcharger tous les parents. Si cela vous cause des ennuis, analysez l’ordre de résolution des méthodes de votre vue.</p>\n<p>Un autre élément à signaler est que les données de contexte provenant des vues génériques basées sur les classes vont écraser les données fournies par les processeurs de contexte ; voir <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_context_data\" title=\"django.views.generic.detail.SingleObjectMixin.get_context_data\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code></a> comme exemple.</p>\n</aside>\n</section>\n<section id=\"viewing-subsets-of-objects\">\n<span id=\"generic-views-list-subsets\"></span><h3>Affichage de sous-ensembles d’objets<a class=\"heading-anchor\" href=\"#viewing-subsets-of-objects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Examinons maintenant un peu plus attentivement le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span></code> que nous avons toujours utilisé. Ce paramètre, qui définit le modèle de base de données sur lequel la vue va porter, est disponible pour toutes les vues génériques qui opèrent sur un seul objet ou une liste d’objets. Cependant, le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span></code> n’est pas le seul moyen de définir le type d’objet d’une vue, il est aussi possible de définir la liste des objets par le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;publisher&#39;</span>\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>L’indication de <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span> <span class=\"pre\">=</span> <span class=\"pre\">Publisher</span></code> est un raccourci pour dire <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span> <span class=\"pre\">=</span> <span class=\"pre\">Publisher.objects.all()</span></code>. Cependant, en utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code> pour définir une liste d’objets filtrée, vous pouvez spécifier plus finement les objets qui seront visibles dans la vue (voir <a class=\"reference internal\" href=\"/fr/4.1/topics/db/queries/\"><span class=\"doc\">Création de requêtes</span></a> pour plus d’informations à propos des objets <a class=\"reference internal\" href=\"/fr/4.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code></a>, et consultez la <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/\"><span class=\"doc\">référence des vues fondées sur les classes</span></a> pour obtenir tous les détails).</p>\n<p>Comme exemple, essayons de trier une liste de livres par date de publication, les plus récents en premier :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BookListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-publication_date&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;book_list&#39;</span>\n</code></pre></div>\n<p>Il s’agit d’un exemple très minimal, mais qui montre bien le principe de fonctionnement. Le but est généralement de faire plus que de simplement trier les objets. Si vous souhaitez présenter une liste de livres provenant d’un éditeur particulier, la même technique peut être utilisée :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AcmeBookListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;book_list&#39;</span>\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">publisher__name</span><span class=\"o\">=</span><span class=\"s1\">&#39;ACME Publishing&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;books/acme_list.html&#39;</span>\n</code></pre></div>\n<p>Remarquez qu’en plus d’un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code> filtré, nous indiquons également un nom de gabarit personnalisé. Sans cela, la vue générique utiliserait le même gabarit que la liste d’objets « standard », ce qui ne correspondrait pas au but recherché.</p>\n<p>Remarquez également que ce n’est pas une façon très élégante d’afficher les livres d’un éditeur particulier. Si nous voulions ensuite ajouter une page pour un autre éditeur, nous devrions ajouter des lignes supplémentaires dans la configuration d’URL et nous serions pratiquement limités à quelques éditeurs. Nous aborderons ce problème dans la section suivante.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Si vous obtenez une erreur 404 en accédant à <code class=\"docutils literal notranslate\"><span class=\"pre\">/books/acme/</span></code>, vérifiez que vous possédez bien un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> dont le nom est « ACME Publishing ». Les vues génériques ont un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">allow_empty</span></code> pour cette situation. Consultez la <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/\"><span class=\"doc\">référence des vues fondées sur les classes</span></a> pour plus de détails.</p>\n</aside>\n</section>\n<section id=\"dynamic-filtering\">\n<h3>Filtrage dynamique<a class=\"heading-anchor\" href=\"#dynamic-filtering\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Un autre besoin fréquent est de filtrer les objets d’une liste selon un critère de l’URL. Plus haut, nous avons figé le nom de l’éditeur dans la configuration d’URL, mais comment faire si nous voulions écrire une vue affichant tous les livres d’un éditeur librement choisi ?</p>\n<p>Heureusement, la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">ListView</span></code> possède une méthode <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_queryset\" title=\"django.views.generic.list.MultipleObjectMixin.get_queryset\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code></a> que nous pouvons surcharger. Par défaut, elle renvoie la valeur du paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code>, mais on peut l’utiliser pour ajouter de la logique supplémentaire.</p>\n<p>L’élément clé pour que cela fonctionne est qu’au moment où les vues fondées sur les classes sont appelées, divers attributs utiles sont créés pour <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code>. En plus de la requête elle-même (<code class=\"docutils literal notranslate\"><span class=\"pre\">self.request</span></code>), il y a aussi les paramètres positionnels (<code class=\"docutils literal notranslate\"><span class=\"pre\">self.args</span></code>) et nommés (<code class=\"docutils literal notranslate\"><span class=\"pre\">self.kwargs</span></code>) capturés en fonction de la configuration d’URL.</p>\n<p>Ici, nous avons une configuration d’URL comportant un seul groupe capturé :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># urls.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">PublisherBookListView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;books/&lt;publisher&gt;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">PublisherBookListView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Puis, nous allons écrire la vue <code class=\"docutils literal notranslate\"><span class=\"pre\">PublisherBookListView</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># views.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_object_or_404</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span><span class=\"p\">,</span> <span class=\"n\">Publisher</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherBookListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;books/books_by_publisher.html&#39;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">publisher</span> <span class=\"o\">=</span> <span class=\"n\">get_object_or_404</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;publisher&#39;</span><span class=\"p\">])</span>\n        <span class=\"k\">return</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">publisher</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">publisher</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset</span></code> pour ajouter de la logique à la sélection du jeu de requête est aussi pratique que puissant. Nous pourrions par exemple filtrer en se basant sur l’utilisateur connecté (<code class=\"docutils literal notranslate\"><span class=\"pre\">self.request.user</span></code>) ou toute autre logique plus complexe.</p>\n<p>Nous pouvons aussi ajouter en même temps l’éditeur dans le contexte, afin de pouvoir l’utiliser dans le gabarit :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># ...</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_context_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Call the base implementation first to get a context</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_context_data</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n    <span class=\"c1\"># Add in the publisher</span>\n    <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;publisher&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">publisher</span>\n    <span class=\"k\">return</span> <span class=\"n\">context</span>\n</code></pre></div>\n</section>\n<section id=\"performing-extra-work\">\n<span id=\"generic-views-extra-work\"></span><h3>Autres opérations supplémentaires<a class=\"heading-anchor\" href=\"#performing-extra-work\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Le dernier usage que nous examinerons concerne les opérations supplémentaires effectuées avant ou après l’appel à la vue générique.</p>\n<p>Imaginez que nous ayons un champ <code class=\"docutils literal notranslate\"><span class=\"pre\">last_accessed</span></code> dans le modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> qui nous sert à garder la trace du moment le plus récent où quelqu’un a consulté la page de cet auteur :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># models.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Author</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">salutation</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    <span class=\"n\">email</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">()</span>\n    <span class=\"n\">headshot</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ImageField</span><span class=\"p\">(</span><span class=\"n\">upload_to</span><span class=\"o\">=</span><span class=\"s1\">&#39;author_headshots&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">last_accessed</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateTimeField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>La classe générique <code class=\"docutils literal notranslate\"><span class=\"pre\">DetailView</span></code> n’a aucune conscience de la présence de ce champ, mais nous pouvons une nouvelle fois écrire une vue personnalisée pour maintenir ce champ à jour.</p>\n<p>Tout d’abord, nous devons ajouter une ligne de détail d’auteur dans la configuration d’URL pour faire le lien avec une vue personnalisée :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">AuthorDetailView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\">#...</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;authors/&lt;int:pk&gt;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">AuthorDetailView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">(),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;author-detail&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Puis il s’agit d’écrire la nouvelle vue. <code class=\"docutils literal notranslate\"><span class=\"pre\">get_object</span></code> étant la méthode qui récupère l’objet, nous la surchargeons en « enveloppant » l’appel par défaut :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timezone</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Author</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_object</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">obj</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_object</span><span class=\"p\">()</span>\n        <span class=\"c1\"># Record the last accessed date</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">last_accessed</span> <span class=\"o\">=</span> <span class=\"n\">timezone</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">obj</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Cette configuration d’URL emploie le group nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code>, il s’agit là du nom par défaut utilisé par <code class=\"docutils literal notranslate\"><span class=\"pre\">DetailView</span></code> pour trouver la valeur de clé primaire à utiliser pour filtrer le jeu de requête.</p>\n<p>Si vous aimeriez nommer différemment le groupe, vous pouvez définir <a class=\"reference internal\" href=\"/fr/4.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.pk_url_kwarg\" title=\"django.views.generic.detail.SingleObjectMixin.pk_url_kwarg\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">pk_url_kwarg</span></code></a> dans la vue.</p>\n</aside>\n</section>\n</section>","rootId":"built-in-class-based-generic-views","toc":[{"title":"Extension des vues génériques","anchor":"extending-generic-views","children":[]},{"title":"Vues génériques d’objets","anchor":"generic-views-of-objects","children":[{"title":"Construction de contextes de gabarits « astucieux »","anchor":"making-friendly-template-contexts","children":[]},{"title":"Ajout de contexte supplémentaire","anchor":"adding-extra-context","children":[]},{"title":"Affichage de sous-ensembles d’objets","anchor":"viewing-subsets-of-objects","children":[]},{"title":"Filtrage dynamique","anchor":"dynamic-filtering","children":[]},{"title":"Autres opérations supplémentaires","anchor":"performing-extra-work","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/4.1/topics/"},{"docname":"topics/class-based-views/index","title":"Vues fondées sur les classes","url":"/fr/4.1/topics/class-based-views/"}],"prev":{"docname":"topics/class-based-views/intro","title":"Introduction aux vues fondées sur les classes","url":"/fr/4.1/topics/class-based-views/intro/"},"next":{"docname":"topics/class-based-views/generic-editing","title":"Gestion de formulaires avec les vues fondées sur les classes","url":"/fr/4.1/topics/class-based-views/generic-editing/"},"formats":{"html":"/fr/4.1/topics/class-based-views/generic-display/","markdown":"/fr/4.1/topics/class-based-views/generic-display.md","json":"/fr/4.1/topics/class-based-views/generic-display.json"},"source":"https://github.com/django/django/blob/stable/4.1.x/docs/topics/class-based-views/generic-display.txt","official":"https://docs.djangoproject.com/fr/4.1/topics/class-based-views/generic-display/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}