{"title":"Intergiciels (« Middleware »)","version":"4.2","locale":"fr","docname":"topics/http/middleware","url":"/fr/4.2/topics/http/middleware/","canonical":"https://djangodocs.dev/fr/4.2/topics/http/middleware/","summary":"Les intergiciels représentent un système de points d’entrée dans le traitement des requêtes et des réponses de Django. C’est un système de greffons léger et de bas…","html":"<h1>Intergiciels (« Middleware »)<a class=\"heading-anchor\" href=\"#middleware\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Les intergiciels représentent un système de points d’entrée dans le traitement des requêtes et des réponses de Django. C’est un système de greffons léger et de bas niveau pour modifier de façon globale les entrées et sorties HTTP de Django.</p>\n<p>Chaque composant d’intergiciel est responsable d’effectuer une tâche spécifique. Par exemple, Django contient un intergiciel, <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware\" title=\"django.contrib.auth.middleware.AuthenticationMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AuthenticationMiddleware</span></code></a>, qui associe les utilisateurs aux requêtes et aux sessions.</p>\n<p>Ce document explique comment fonctionnent les intergiciels, la manière de les activer et d’écrire vos propres intergiciels. Django est livré avec quelques intergiciels intégrés qu’il est possible d’utiliser tels quels. Ils sont documentés dans la <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/\"><span class=\"doc\">référence des intergiciels intégrés</span></a>.</p>\n<section id=\"writing-your-own-middleware\">\n<h2>Écriture de son propre intergiciel<a class=\"heading-anchor\" href=\"#writing-your-own-middleware\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Une fabrique d’intergiciel est un objet exécutable acceptant un exécutable <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> et renvoyant un intergiciel. Un intergiciel est un objet exécutable acceptant une requête et renvoyant une réponse, tout comme une vue.</p>\n<p>Un intergiciel peut être écrit comme une fonction qui ressemble à ceci :</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=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">simple_middleware</span><span class=\"p\">(</span><span class=\"n\">get_response</span><span class=\"p\">):</span>\n    <span class=\"c1\"># One-time configuration and initialization.</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">middleware</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Code to be executed for each request before</span>\n        <span class=\"c1\"># the view (and later middleware) are called.</span>\n\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">get_response</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Code to be executed for each request/response after</span>\n        <span class=\"c1\"># the view is called.</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">response</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">middleware</span>\n</code></pre></div>\n<p>Ou il peut être écrit comme une classe dont les instances peuvent être appelées, comme ceci :</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=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SimpleMiddleware</span><span class=\"p\">:</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">get_response</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_response</span> <span class=\"o\">=</span> <span class=\"n\">get_response</span>\n        <span class=\"c1\"># One-time configuration and initialization.</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__call__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Code to be executed for each request before</span>\n        <span class=\"c1\"># the view (and later middleware) are called.</span>\n\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_response</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Code to be executed for each request/response after</span>\n        <span class=\"c1\"># the view is called.</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n<p>L’exécutable <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> fournit par Django pourrait être la vue elle-même (s’il s’agit du dernier intergiciel) ou alors le prochain intergiciel dans la chaîne. L’intergiciel actuel n’a pas besoin de savoir ou de se préoccuper de ce que c’est exactement, il lui suffit de savoir que ça représente ce qui vient ensuite.</p>\n<p>Nous avons un peu simplifié l’explication ci-dessus, car l’exécutable <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> du dernier intergiciel dans la chaîne est en fait une méthode enveloppant la vue, créée par le gestionnaire se chargeant d’appliquer les <a class=\"reference internal\" href=\"#view-middleware\"><span class=\"std std-ref\">intergiciels de vue</span></a>; cette méthode appelle la vue avec les paramètres appropriés et applique les intergiciels <a class=\"reference internal\" href=\"#template-response-middleware\"><span class=\"std std-ref\">template-response</span></a> et <a class=\"reference internal\" href=\"#exception-middleware\"><span class=\"std std-ref\">exception</span></a>.</p>\n<p>Un intergiciel peut soit uniquement prendre en charge le code Python synchrone (par défaut), soit uniquement du code asynchrone, ou encore les deux. Consultez <a class=\"reference internal\" href=\"#async-middleware\"><span class=\"std std-ref\">Gestion du code asynchrone</span></a> pour des détails sur la manière d’informer sur ce qui est pris en charge et pour connaître le genre de requête que vous obtenez.</p>\n<p>Les intergiciels peuvent se trouver n’importe où dans votre chemin Python.</p>\n<section id=\"init-get-response\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">__init__(get_response)</span></code><a class=\"heading-anchor\" href=\"#init-get-response\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les fabriques d’intergiciel doivent accepter un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code>. Il est aussi possible d’initialiser de l’état global pour l’intergiciel. Gardez à l’esprit quelques précautions :</p>\n<ul class=\"simple\">\n<li><p>Django initialise les intergiciels avec le seul paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code>, il n’est donc pas possible de définir d’autres paramètres obligatoires à <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code>.</p></li>\n<li><p>Contrairement à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__call__()</span></code> qui est appelée une fois par requête, <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> n’est appelée qu”<em>une seule fois</em>, lorsque le serveur web démarre.</p></li>\n</ul>\n</section>\n<section id=\"marking-middleware-as-unused\">\n<h3>Signalement d’un intergiciel à exclure<a class=\"heading-anchor\" href=\"#marking-middleware-as-unused\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il est parfois utile de déterminer au moment du démarrage si un intergiciel doit être utilisé. Dans ces cas, la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> de l’intergiciel peut générer l’exception <a class=\"reference internal\" href=\"/fr/4.2/ref/exceptions/#django.core.exceptions.MiddlewareNotUsed\" title=\"django.core.exceptions.MiddlewareNotUsed\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">MiddlewareNotUsed</span></code></a>. Django se charge alors d’enlever cet intergiciel du processus des intergiciels et jouranlise un message de débogage vers le journaliseur <a class=\"reference internal\" href=\"/fr/4.2/ref/logging/#django-request-logger\"><span class=\"std std-ref\">django.request</span></a> lorsque  <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n</section>\n</section>\n<section id=\"activating-middleware\">\n<h2>Activation des intergiciels<a class=\"heading-anchor\" href=\"#activating-middleware\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour activer un intergiciel, ajoutez son chemin dans la liste <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> de vos réglages Django.</p>\n<p>Dans <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>, chaque intergiciel est représenté par une chaîne : le chemin Python complet vers le nom de la classe ou de la fonction de fabrique d’intergiciel. Par exemple, voici la valeur par défaut créée par <a class=\"reference internal\" href=\"/fr/4.2/ref/django-admin/#django-admin-startproject\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">django-admin</span> <span class=\"pre\">startproject</span></code></a>:</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=\"n\">MIDDLEWARE</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s2\">&quot;django.middleware.security.SecurityMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.contrib.sessions.middleware.SessionMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.middleware.common.CommonMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.middleware.csrf.CsrfViewMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.contrib.auth.middleware.AuthenticationMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.contrib.messages.middleware.MessageMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.middleware.clickjacking.XFrameOptionsMiddleware&quot;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Une installation de Django n’a pas nécessairement des intergiciels, <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> pouvant très bien être vide si vous le souhaitez, mais il est fortement recommandé d’utiliser au moins <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/#django.middleware.common.CommonMiddleware\" title=\"django.middleware.common.CommonMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CommonMiddleware</span></code></a>.</p>\n<p>L’ordre dans <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> a son importance car un intergiciel peut dépendre d’un autre. Par exemple, <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware\" title=\"django.contrib.auth.middleware.AuthenticationMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AuthenticationMiddleware</span></code></a> stocke l’utilisateur non authentifié dans la session ; il doit donc être exécuté après <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/#django.contrib.sessions.middleware.SessionMiddleware\" title=\"django.contrib.sessions.middleware.SessionMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SessionMiddleware</span></code></a>. Voir <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/#middleware-ordering\"><span class=\"std std-ref\">Ordre des intergiciels</span></a> pour d’autres indications utiles concernant l’ordre des classes d’intergiciel de Django.</p>\n</section>\n<section id=\"middleware-order-and-layering\">\n<h2>Ordre des intergiciels et empilement<a class=\"heading-anchor\" href=\"#middleware-order-and-layering\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Durant la phase de requête, avant d’appeler la vue, Django applique les intergiciels dans l’ordre où ils sont définis dans <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>, de haut en bas.</p>\n<p>Vous pouvez l’imaginer comme un oignon : chaque classe d’intergiciel est une « couche » qui enveloppe la vue, elle-même le cœur de l’oignon. Si la requête traverse toutes les couches de l’oignon (chacune appelant <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> pour passer la requête à la prochaine couche), jusqu’à atteindre la vue au cœur, la réponse va ensuite traverser elle-même toutes les couches (dans l’ordre inverse) jusqu’à sa sortie du mécanisme.</p>\n<p>Si l’une des couches décide de court-circuiter et de renvoyer une réponse sans jamais appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code>, aucune des couches de l’oignon plus à l’intérieur de cette couche (y compris la vue) ne verra la requête ou la réponse. La réponse ne traversera toujours que les mêmes couches traversées par la requête.</p>\n</section>\n<section id=\"other-middleware-hooks\">\n<h2>Autres points d’entrée d’intergiciel<a class=\"heading-anchor\" href=\"#other-middleware-hooks\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>En dehors du modèle basique requête/réponse d’intergiciel présenté précédemment, vous pouvez ajouter trois autres méthodes spéciales aux intergiciels basés sur des classes :</p>\n<section id=\"process-view\">\n<span id=\"view-middleware\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">process_view()</span></code><a class=\"heading-anchor\" href=\"#process-view\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"process_view\">\n<span class=\"sig-name descname\"><span class=\"pre\">process_view</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">request</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view_func</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view_args</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view_kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#process_view\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> est un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a>. <code class=\"docutils literal notranslate\"><span class=\"pre\">view_func</span></code> et la fonction python que Django s’apprête à utiliser (il s’agit bien de l’objet fonction, pas du nom textuel de la fonction). <code class=\"docutils literal notranslate\"><span class=\"pre\">view_args</span></code> est une liste de paramètres positionnels qui seront transmis à la vue, et <code class=\"docutils literal notranslate\"><span class=\"pre\">view_kwargs</span></code> est un dictionnaire de paramètres nommés qui seront transmis à la vue. Ni <code class=\"docutils literal notranslate\"><span class=\"pre\">view_args</span></code> ni <code class=\"docutils literal notranslate\"><span class=\"pre\">view_kwargs</span></code> ne comprennent le premier paramètre de la vue (<code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code>).</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">process_view()</span></code> est appelée juste avant que Django n’appelle la vue.</p>\n<p>Elle doit renvoyer soit <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, soit un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>. Si elle renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, Django continue le traitement de la requête, en appliquant d’éventuels autres intergiciels <code class=\"docutils literal notranslate\"><span class=\"pre\">process_view()</span></code>, puis exécute la vue appropriée. Si elle renvoie un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>, Django ne prend pas la peine d’appeler la vue correspondante ; il va simplement appliquer les intergiciels de réponse à cet objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> et renvoyer le résultat.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>L’accès à <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpRequest.POST\" title=\"django.http.HttpRequest.POST\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">request.POST</span></code></a> depuis un intergiciel avant que la vue ne soit exécutée ou dans <code class=\"docutils literal notranslate\"><span class=\"pre\">process_view()</span></code> empêche toute vue exécutée après les intergiciels de pouvoir <a class=\"reference internal\" href=\"/fr/4.2/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly\"><span class=\"std std-ref\">modifier les gestionnaires de téléversement de la requête</span></a>, et devrait donc être évité.</p>\n<p>La classe <a class=\"reference internal\" href=\"/fr/4.2/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware\" title=\"django.middleware.csrf.CsrfViewMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code></a> peut être considérée comme une exception, car elle fournit les décorateurs <a class=\"reference internal\" href=\"/fr/4.2/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a> et <a class=\"reference internal\" href=\"/fr/4.2/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a> qui permettent aux vues de contrôler explicitement le moment de la validation CSRF.</p>\n</aside>\n</section>\n<section id=\"process-exception\">\n<span id=\"exception-middleware\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception()</span></code><a class=\"heading-anchor\" href=\"#process-exception\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"process_exception\">\n<span class=\"sig-name descname\"><span class=\"pre\">process_exception</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">request</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">exception</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#process_exception\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> est un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a>. <code class=\"docutils literal notranslate\"><span class=\"pre\">exception</span></code> est un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Exception</span></code> généré par la fonction de vue.</p>\n<p>Django appelle <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception()</span></code> lorsqu’une vue génère une exception. <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception()</span></code> doit renvoyer <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> ou un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>. Si elle renvoie un objet  <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>, les intergiciels de réponse par gabarit et de réponse sont appliqués, et la réponse résultante sera renvoyée au navigateur. Sinon, la <a class=\"reference internal\" href=\"/fr/4.2/ref/views/#error-views\"><span class=\"std std-ref\">gestion par défaut des exceptions</span></a> intervient.</p>\n<p>Encore une fois, les intergiciels sont exécutés dans l’ordre inverse lors de la phase de réponse, ce qui comprend <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception</span></code>. Si un intergiciel d’exception renvoie une réponse, les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception</span></code> des classes d’intergiciels situées au-dessus ne seront pas du tout appelées.</p>\n</section>\n<section id=\"process-template-response\">\n<span id=\"template-response-middleware\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">process_template_response()</span></code><a class=\"heading-anchor\" href=\"#process-template-response\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"process_template_response\">\n<span class=\"sig-name descname\"><span class=\"pre\">process_template_response</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">request</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#process_template_response\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> est un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a>. <code class=\"docutils literal notranslate\"><span class=\"pre\">response</span></code> est l’objet <a class=\"reference internal\" href=\"/fr/4.2/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> (ou équivalent) renvoyé par une vue Django ou par un intergiciel.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">process_template_response()</span></code> est appelée juste après la fin de l’exécution de la vue, pour autant que l’instance réponse possède une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code>, ce qui laisse penser qu’il s’agit d’un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> ou d’un équivalent.</p>\n<p>Elle doit renvoyer un objet réponse qui implémente une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code>. Elle peut modifier la réponse donnée en changeant <code class=\"docutils literal notranslate\"><span class=\"pre\">response.template_name</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">response.context_data</span></code>, ou elle peut créer et renvoyer une toute nouvelle classe <a class=\"reference internal\" href=\"/fr/4.2/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> ou un équivalent.</p>\n<p>Il n’est pas nécessaire d’effectuer explicitement le rendu des réponses, celles-ci étant automatiquement « rendues » après que tous les intergiciels de réponse ont été appelés.</p>\n<p>Les intergiciels sont exécutés dans l’ordre inverse lors de la phase de réponse, ce qui inclut <code class=\"docutils literal notranslate\"><span class=\"pre\">process_template_response()</span></code>.</p>\n</section>\n</section>\n<section id=\"dealing-with-streaming-responses\">\n<h2>Gestion des réponses en flux<a class=\"heading-anchor\" href=\"#dealing-with-streaming-responses\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Au contraire de <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>, <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.StreamingHttpResponse\" title=\"django.http.StreamingHttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StreamingHttpResponse</span></code></a> ne possède pas d’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">content</span></code>. En conséquence, les intergiciels ne peuvent plus compter sur le fait que toutes les réponses possèdent un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">content</span></code>. S’ils ont besoin d’accéder au contenu, ils doivent savoir s’ils ont affaire avec une réponse de type flux (streaming) et ajuster leur comportement en fonction de cela :</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=\"k\">if</span> <span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">streaming</span><span class=\"p\">:</span>\n    <span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">streaming_content</span> <span class=\"o\">=</span> <span class=\"n\">wrap_streaming_content</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">streaming_content</span><span class=\"p\">)</span>\n<span class=\"k\">else</span><span class=\"p\">:</span>\n    <span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">content</span> <span class=\"o\">=</span> <span class=\"n\">alter_content</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">content</span><span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Il faut toujours partir du principe que <code class=\"docutils literal notranslate\"><span class=\"pre\">streaming_content</span></code> est trop volumineux pour être stocké en mémoire. Les intergiciels de réponse peuvent l’adapter dans un nouveau générateur, mais ils ne devraient pas le consommer. L’adaptation s’implémente typiquement de cette façon :</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=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">wrap_streaming_content</span><span class=\"p\">(</span><span class=\"n\">content</span><span class=\"p\">):</span>\n    <span class=\"k\">for</span> <span class=\"n\">chunk</span> <span class=\"ow\">in</span> <span class=\"n\">content</span><span class=\"p\">:</span>\n        <span class=\"k\">yield</span> <span class=\"n\">alter_content</span><span class=\"p\">(</span><span class=\"n\">chunk</span><span class=\"p\">)</span>\n</code></pre></div>\n</aside>\n<p><a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.StreamingHttpResponse\" title=\"django.http.StreamingHttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StreamingHttpResponse</span></code></a> autorise à la fois les itérateurs synchrones et asynchrones. La fonction enveloppeuse doit correspondre. Vérifiez <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.StreamingHttpResponse.is_async\" title=\"django.http.StreamingHttpResponse.is_async\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">StreamingHttpResponse.is_async</span></code></a> si votre intergiciel doit prendre en charge les deux types d’itérateur.</p>\n<aside class=\"version-note version-changed\" data-version=\"4.2\">\n<p class=\"version-note-title\">Changed in Django 4.2</p><p>La prise en charge des réponses en flux avec des itérateurs asynchrones a été ajoutée.</p>\n</aside>\n</section>\n<section id=\"exception-handling\">\n<h2>Gestion des exceptions<a class=\"heading-anchor\" href=\"#exception-handling\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django convertit automatiquement les exceptions produites par la vue ou par l’intergiciel en une réponse HTTP appropriée avec un code de statut d’erreur. <a class=\"reference internal\" href=\"/fr/4.2/ref/views/#error-views\"><span class=\"std std-ref\">Certaine exceptions</span></a> sont converties en codes de statut 4xx, alors qu’une exception inconnue est convertie en un code de statut 500.</p>\n<p>Cette conversion a lieu avant et après chaque intergiciel (vous pouvez vous représenter cela comme la fine peau entre chaque couche de l’oignon), afin que chaque intergiciel puisse toujours compter sur l’obtention d’un certain type de réponse HTTP en retour de son appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code>. Les intergiciels n’ont pas besoin se se soucier d’envelopper leur appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> dans un bloc <code class=\"docutils literal notranslate\"><span class=\"pre\">try/except</span></code> pour gérer une exception qui aurait pu être générée par un intergiciel suivant ou par la vue. Même si l’intergiciel suivant dans la chaîne génère une exception <a class=\"reference internal\" href=\"/fr/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a>, par exemple, votre intergiciel ne verra pas cette exception ; il obtiendra à la place un objet <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> avec un code <a class=\"reference internal\" href=\"/fr/4.2/ref/request-response/#django.http.HttpResponse.status_code\" title=\"django.http.HttpResponse.status_code\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">status_code</span></code></a> 404.</p>\n<p>Vous pouvez définir <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-DEBUG_PROPAGATE_EXCEPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG_PROPAGATE_EXCEPTIONS</span></code></a> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> pour omettre cette conversion et propager les exceptions au niveau supérieur.</p>\n</section>\n<section id=\"asynchronous-support\">\n<span id=\"async-middleware\"></span><h2>Gestion du code asynchrone<a class=\"heading-anchor\" href=\"#asynchronous-support\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les intergiciels peuvent prendre en charge n’importe quelle combinaison de requêtes synchrones et asynchrones. Django adapte les requêtes pour correspondre aux exigences des intergiciels si ceux-ci ne gèrent pas les deux types de requêtes, mais avec une baisse de performance.</p>\n<p>Par défaut, Django part du principe qu’un intergiciel n’est capable de traiter que des requêtes synchrones. Pour modifier ce présupposé, définissez les attributs suivants sur la classe ou la fonction fabriquante d’intergiciel :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">sync_capable</span></code> est une variable booléenne indiquant si l’intergiciel peut gérer des requêtes synchrones. Vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> par défaut.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">async_capable</span></code> est une variable booléenne indiquant si l’intergiciel peut gérer des requêtes asynchrones. Vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> par défaut.</p></li>\n</ul>\n<p>Si un intergiciel possède à la fois <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_capable</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">async_capable</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code>,  Django lui transmet la requête sans la modifier. Dans ce cas, l’intergiciel peut savoir si la requête qu’il reçoit est asynchrone ou pas en vérifiant si l’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> qu’il reçoit est une fonction coroutine, à l’aide de <code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref.sync.iscoroutinefunction</span></code>.</p>\n<p>Le module <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.decorators</span></code> contient les décorateurs <a class=\"reference internal\" href=\"/fr/4.2/ref/utils/#django.utils.decorators.sync_only_middleware\" title=\"django.utils.decorators.sync_only_middleware\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_only_middleware()</span></code></a>, <a class=\"reference internal\" href=\"/fr/4.2/ref/utils/#django.utils.decorators.async_only_middleware\" title=\"django.utils.decorators.async_only_middleware\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_only_middleware()</span></code></a> et <a class=\"reference internal\" href=\"/fr/4.2/ref/utils/#django.utils.decorators.sync_and_async_middleware\" title=\"django.utils.decorators.sync_and_async_middleware\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_and_async_middleware()</span></code></a> qui permettent d’attribuer les drapeaux adéquats aux fonctions fabriquantes d’intergiciels.</p>\n<p>L’objet exécutable renvoyé doit correspondre à la nature synchrone ou asynchrone de la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code>. Si vous recevez un <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> asynchrone, vous devez renvoyer une fonction coroutine (<code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code>).</p>\n<p>Les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">process_view</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">process_template_response</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception</span></code>, quand elles sont présentes, doivent aussi être adaptées pour les modes synchrones/asynchrones. Cependant, Django les adapte individuellement si vous ne le faites pas, mais avec une perte de performance supplémentaire.</p>\n<p>Voici un exemple de la manière de créer une fonction d’intergiciel qui prend en charge les deux modes</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\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">iscoroutinefunction</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.decorators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_and_async_middleware</span>\n\n\n<span class=\"nd\">@sync_and_async_middleware</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">simple_middleware</span><span class=\"p\">(</span><span class=\"n\">get_response</span><span class=\"p\">):</span>\n    <span class=\"c1\"># One-time configuration and initialization goes here.</span>\n    <span class=\"k\">if</span> <span class=\"n\">iscoroutinefunction</span><span class=\"p\">(</span><span class=\"n\">get_response</span><span class=\"p\">):</span>\n\n        <span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">middleware</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n            <span class=\"c1\"># Do something here!</span>\n            <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">get_response</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n            <span class=\"k\">return</span> <span class=\"n\">response</span>\n\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n\n        <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">middleware</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n            <span class=\"c1\"># Do something here!</span>\n            <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">get_response</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n            <span class=\"k\">return</span> <span class=\"n\">response</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">middleware</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Si vous déclarez un intergiciel hybride qui prend en charge à la fois les appels synchrones et asynchrones, le type d’appel que vous obtenez pourrait ne pas correspondre à la vue sous-jacente. Django optimise la pile d’appel des intergiciels pour qu’il y ait le moins de transitions synchrones/asynchrones que possible.</p>\n<p>Ainsi, même si vous enveloppez une vue asynchrone, elle pourrait être appelée en mode synchrone s’il y a d’autres intergiciels synchrones entre son exécution et la vue.</p>\n</aside>\n<p>Lorsque vous utilisez un intergiciel asynchrone basé sur une classe, vous devez vous assurer que les instances sont correctement marquées comme des fonctions coroutines</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\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">iscoroutinefunction</span><span class=\"p\">,</span> <span class=\"n\">markcoroutinefunction</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AsyncMiddleware</span><span class=\"p\">:</span>\n    <span class=\"n\">async_capable</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n    <span class=\"n\">sync_capable</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">get_response</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_response</span> <span class=\"o\">=</span> <span class=\"n\">get_response</span>\n        <span class=\"k\">if</span> <span class=\"n\">iscoroutinefunction</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_response</span><span class=\"p\">):</span>\n            <span class=\"n\">markcoroutinefunction</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span>\n\n    <span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__call__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_response</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Some logic ...</span>\n        <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n</section>\n<section id=\"upgrading-pre-django-1-10-style-middleware\">\n<span id=\"upgrading-middleware\"></span><h2>Mise à jour d’intergiciels écrits avant Django 1.10<a class=\"heading-anchor\" href=\"#upgrading-pre-django-1-10-style-middleware\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.utils.deprecation.MiddlewareMixin\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">django.utils.deprecation.</span></span><span class=\"sig-name descname\"><span class=\"pre\">MiddlewareMixin</span></span><a class=\"heading-anchor\" href=\"#django.utils.deprecation.MiddlewareMixin\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Django fournit <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.deprecation.MiddlewareMixin</span></code> pour faciliter la création de classes d’intergiciel qui sont compatibles à la fois avec <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> et l’ancien <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code>, et qui prennent en charge les requêtes synchrones et asynchrones. Toutes les classes d’intergiciel incluses dans Django sont compatibles avec les deux réglages.</p>\n<p>Cette classe « mixin » fournit une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> exigeant un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">get_response</span></code> et le stockant dans <code class=\"docutils literal notranslate\"><span class=\"pre\">self.get_response</span></code>.</p>\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__call__()</span></code>:</p>\n<ol class=\"arabic simple\">\n<li><p>Appelle <code class=\"docutils literal notranslate\"><span class=\"pre\">self.process_request(request)</span></code> (si elle est définie).</p></li>\n<li><p>Appelle <code class=\"docutils literal notranslate\"><span class=\"pre\">self.get_response(request)</span></code> pour obtenir la réponse du dernier intergiciel et de la vue.</p></li>\n<li><p>Appelle <code class=\"docutils literal notranslate\"><span class=\"pre\">self.process_response(request,</span> <span class=\"pre\">response)</span></code> (si elle est définie).</p></li>\n<li><p>Renvoie la réponse.</p></li>\n</ol>\n<p>Quand elle est utilisée avec <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code>, la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">__call__()</span></code> ne sera jamais utilisée ; Django appelle directement <code class=\"docutils literal notranslate\"><span class=\"pre\">process_request()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">process_response()</span></code>.</p>\n<p>Dans la plupart des cas, l’héritage de cette classe « mixin » suffit à rendre compatible un intergiciel ancien style avec le nouveau système avec suffisamment de rétro-compatibilité. La nouvelle sémantique de court-circuitage ne fera pas de mal ou sera même avantageuse pour l’intergiciel existant. Dans quelques cas, une classe d’intergiciel pourrait avoir besoin de certains changements pour s’ajuster à la nouvelle sémantique.</p>\n<p>Voici les différences de comportement entre l’utilisation de <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> et de <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code>:</p>\n<ol class=\"arabic simple\">\n<li><p>Avec <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code>, chaque intergiciel verra toujours sa méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">process_response</span></code> appelée, même si un intergiciel précédent a court-circuité le processus en renvoyant une réponse de sa méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">process_request</span></code>. Avec <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>, les intergiciels se comportent plus comme un oignon : les couches que parcourt une réponse jusqu’à sa sortie sont les mêmes que la requête a vu passer dans le sens inverse. Si un intergiciel court-circuite, seul cet intergiciel et ceux qui le précèdent dans <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> verront passer la réponse.</p></li>\n<li><p>Avec <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception</span></code> est appliquée aux exceptions générées depuis une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">process_request</span></code> d’intergiciel. Avec <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>, <code class=\"docutils literal notranslate\"><span class=\"pre\">process_exception</span></code> ne s’applique qu’aux exceptions générées dans la vue (ou depuis la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code> d’une réponse <a class=\"reference internal\" href=\"/fr/4.2/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a>). Les exceptions générées depuis un intergiciel sont converties en une réponse HTTP appropriée puis transmises à l’intergiciel suivant.</p></li>\n<li><p>Avec <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code>, si une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">process_response</span></code> génère une exception, les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">process_response</span></code> de tous les intergiciels précédents sont omises et une réponse HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">500</span> <span class=\"pre\">erreur</span> <span class=\"pre\">de</span> <span class=\"pre\">serveur</span> <span class=\"pre\">interne</span></code> est toujours renvoyée (même si l’exception générée était par exemple <a class=\"reference internal\" href=\"/fr/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a>). Avec <a class=\"reference internal\" href=\"/fr/4.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>, une exception générée depuis un intergiciel est immédiatement convertie en une réponse HTTP appropriée, puis le prochain intergiciel dans la chaîne verra la réponse. Les intergiciels ne sont jamais outrepassés en raison d’une exception générée dans un autre intergiciel.</p></li>\n</ol>\n</section>","rootId":"middleware","toc":[{"title":"Écriture de son propre intergiciel","anchor":"writing-your-own-middleware","children":[{"title":"__init__(get_response)","anchor":"init-get-response","children":[]},{"title":"Signalement d’un intergiciel à exclure","anchor":"marking-middleware-as-unused","children":[]}]},{"title":"Activation des intergiciels","anchor":"activating-middleware","children":[]},{"title":"Ordre des intergiciels et empilement","anchor":"middleware-order-and-layering","children":[]},{"title":"Autres points d’entrée d’intergiciel","anchor":"other-middleware-hooks","children":[{"title":"process_view()","anchor":"process-view","children":[]},{"title":"process_exception()","anchor":"process-exception","children":[]},{"title":"process_template_response()","anchor":"process-template-response","children":[]}]},{"title":"Gestion des réponses en flux","anchor":"dealing-with-streaming-responses","children":[]},{"title":"Gestion des exceptions","anchor":"exception-handling","children":[]},{"title":"Gestion du code asynchrone","anchor":"asynchronous-support","children":[]},{"title":"Mise à jour d’intergiciels écrits avant Django 1.10","anchor":"upgrading-pre-django-1-10-style-middleware","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/4.2/topics/"},{"docname":"topics/http/index","title":"Gestion des requêtes HTTP","url":"/fr/4.2/topics/http/"}],"prev":{"docname":"topics/http/generic-views","title":"Vues génériques","url":"/fr/4.2/topics/http/generic-views/"},"next":{"docname":"topics/http/sessions","title":"Utilisation des sessions","url":"/fr/4.2/topics/http/sessions/"},"formats":{"html":"/fr/4.2/topics/http/middleware/","markdown":"/fr/4.2/topics/http/middleware.md","json":"/fr/4.2/topics/http/middleware.json"},"source":"https://github.com/django/django/blob/stable/4.2.x/docs/topics/http/middleware.txt","official":"https://docs.djangoproject.com/fr/4.2/topics/http/middleware/","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"]}