{"title":"L’infrastructure de cache dans Django","version":"1.10","locale":"fr","docname":"topics/cache","url":"/fr/1.10/topics/cache/","canonical":"https://djangodocs.dev/fr/1.10/topics/cache/","summary":"Un site Web crée avec Django est dynamique. Chaque fois qu’un utilisateur demande l’affichage d’une page, le serveur Web effectue toutes sortes d’opérations – des…","html":"<h1>L’infrastructure de cache dans Django<a class=\"heading-anchor\" href=\"#django-s-cache-framework\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Un site Web crée avec Django est dynamique. Chaque fois qu’un utilisateur demande l’affichage d’une page, le serveur Web effectue toutes sortes d’opérations – des requêtes de bases de données au rendu des gabarits, en plus de la logique métier de l’application – afin de créer les pages que vos visiteurs verront. Ces opérations sont bien plus chères en temps de calcul qu’un site Web statique, ou des pages seraient directement lues depuis le système de fichier.</p>\n<p>Pour la plupart des applications Web, cette charge supplémentaire n’est pas un problème. En effet, la plupart des sites Web n’ont pas la popularité de <code class=\"docutils literal notranslate\"><span class=\"pre\">washingtonpost.com</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">slashdot.org</span></code>, mais sont simplement des sites petits ou moyens, avec un trafic bien plus faible. En revanche, pour les sites à trafic moyen ou lourd, il est essentiel de réduire la charge de travail du serveur au maximum.</p>\n<p>C’est là que le cache intervient.</p>\n<p>Mettre quelque chose « en cache » est le fait de sauvegarder le résultat d’une opération chère en temps de calcul, afin de ne pas avoir à ré-effectuer cette opération la fois suivante.</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\">given</span> <span class=\"n\">a</span> <span class=\"n\">URL</span><span class=\"p\">,</span> <span class=\"k\">try</span> <span class=\"n\">finding</span> <span class=\"n\">that</span> <span class=\"n\">page</span> <span class=\"ow\">in</span> <span class=\"n\">the</span> <span class=\"n\">cache</span>\n<span class=\"k\">if</span> <span class=\"n\">the</span> <span class=\"n\">page</span> <span class=\"ow\">is</span> <span class=\"ow\">in</span> <span class=\"n\">the</span> <span class=\"n\">cache</span><span class=\"p\">:</span>\n    <span class=\"k\">return</span> <span class=\"n\">the</span> <span class=\"n\">cached</span> <span class=\"n\">page</span>\n<span class=\"k\">else</span><span class=\"p\">:</span>\n    <span class=\"n\">generate</span> <span class=\"n\">the</span> <span class=\"n\">page</span>\n    <span class=\"n\">save</span> <span class=\"n\">the</span> <span class=\"n\">generated</span> <span class=\"n\">page</span> <span class=\"ow\">in</span> <span class=\"n\">the</span> <span class=\"n\">cache</span> <span class=\"p\">(</span><span class=\"k\">for</span> <span class=\"nb\">next</span> <span class=\"n\">time</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">the</span> <span class=\"n\">generated</span> <span class=\"n\">page</span>\n</code></pre></div>\n<p>Django mets un système de cache robuste à disposition, qui permet de sauvegarder les pages dynamiques afin d’éviter leur calcul pour chaque requête. Pour plus de souplesse, Django propose différents niveaux de granularité de cache: il est possible de mettre en cache le résultat de vues spécifiques, seulement les parties difficiles à produire, ou l’intégralité de votre site.</p>\n<p>Django fonctionne aussi très bien avec des caches externes tels que <a class=\"reference external\" href=\"http://www.squid-cache.org\">Squid</a>, ainsi que les caches des navigateurs.\nCes types de caches ne sont pas controlés directement par l’application. Il est en revanche possible de leur fournir des indices (via les entêtes HTTP) sur quelles parties de votre site mettre en cache, et comment.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p>La  <a class=\"reference internal\" href=\"/fr/1.10/misc/design-philosophies/#cache-design-philosophy\"><span class=\"std std-ref\">philosophie de conception du système de cache</span></a> explique quelques-unes des décisions de conception de ce système.</p>\n</aside>\n<section id=\"setting-up-the-cache\">\n<span id=\"id1\"></span><h2>Mise en place du cache<a class=\"heading-anchor\" href=\"#setting-up-the-cache\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Le système de cache nécessite un peu de mise en place. En particulier, il faut indiquer où les données mises en cache doivent être stockées – dans une base de données, dans le système de fichiers ou directement en mémoire. C’est une décision importante qui influe sur les performances de votre cache: oui, certains systèmes sont plus rapides que d’autres.</p>\n<p>Le choix de votre lieu de stockage de données de cache s’effectue à l’aide de l’entrée <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a> de votre fichier de réglages. Voici les valeurs possibles de <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a>.</p>\n<section id=\"memcached\">\n<span id=\"id2\"></span><h3>Memcached<a class=\"heading-anchor\" href=\"#memcached\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Le type de cache le plus rapide et le plus efficace parmi ceux pris en charge nativement par Django, <a class=\"reference external\" href=\"http://memcached.org/\">Memcached</a> est un serveur de cache entièrement basé en mémoire, développé à l’origine pour soutenir la charge de travail élevée de LiveJournal.com, et dont la source a été par la suite ouverte par Danga Interactive. De gros sites tels que Facebook et Wikipedia l’utilisent pour réduire le nombre d’accès à leurs bases de données et accroître les performances de leurs sites en général.</p>\n<p>Memcached fonctionne comme un service et reçoit une quantité de mémoire vive définie. Son unique rôle est de fournir une interface rapide pour ajouter, récupérer et supprimer des données dans le cache. Toutes les données sont stockées directement en mémoire, il n’y a donc aucune charge induite par une base de données ou par le système de fichiers.</p>\n<p>Après avoir installé Memcached, il s’agit d’installer le code de liaison Memcached. Il existe plusieurs codes de liaison Memcached disponibles en Python ; les deux les plus populaires sont <a class=\"reference external\" href=\"https://pypi.python.org/pypi/python-memcached\">python-memcached</a> et <a class=\"reference external\" href=\"https://pypi.python.org/pypi/pylibmc\">pylibmc</a>.</p>\n<p>Pour utiliser Memcached avec Django :</p>\n<ul class=\"simple\">\n<li><p>Définissez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> à <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.cache.backends.memcached.MemcachedCache</span></code> ou à <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.cache.backends.memcached.PyLibMCCache</span></code> (selon votre choix de code de liaison memcached)</p></li>\n<li><p>Définissez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a> aux valeurs <code class=\"docutils literal notranslate\"><span class=\"pre\">ip:port</span></code>, où <code class=\"docutils literal notranslate\"><span class=\"pre\">ip</span></code> est l’adresse IP du service Memcached  et <code class=\"docutils literal notranslate\"><span class=\"pre\">port</span></code> est le port de fonctionnement de Memcached,  ou à une valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">unix:path</span></code>, où <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> est le chemin vers le fichier connecteur Unix de  Memcached.</p></li>\n</ul>\n<p>Dans cet exemple, Memcached tourne sur localhost (127.0.0.1) port 11211, utilisant la liaison <code class=\"docutils literal notranslate\"><span class=\"pre\">python-memcached</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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.memcached.MemcachedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;127.0.0.1:11211&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Dans cet exemple, Memcached est disponible par un connecteur Unix local <code class=\"file docutils literal notranslate\"><span class=\"pre\">/tmp/memcached.sock</span></code> en utilisant la liaison <code class=\"docutils literal notranslate\"><span class=\"pre\">python-memcached</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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.memcached.MemcachedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;unix:/tmp/memcached.sock&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Si vous utilisez le code de liaison <code class=\"docutils literal notranslate\"><span class=\"pre\">pylibmc</span></code>, n’utilisez pas le préfixe <code class=\"docutils literal notranslate\"><span class=\"pre\">unix:/</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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.memcached.PyLibMCCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;/tmp/memcached.sock&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>L’une des fonctionnalités très intéressantes de Memcached est de pouvoir répartir un cache sur plusieurs serveurs. Cela signifie que vous pouvez faire fonctionner des services Memcached sur plusieurs machines et le programme va considérer le groupe de machines comme un <em>seul</em> cache, sans devoir dupliquer les valeurs du cache sur chaque machine. Pour tirer profit de cette fonctionnalité, ajoutez toutes les adresses des serveurs impliqués dans <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a>, soit en les séparant par des points-virgules ou sous forme de liste.</p>\n<p>Dans cet exemple, le cache est distribué sur des instances Memcached fonctionnant aux adresses IP 172.19.26.240 et 172.19.26.242, les deux sur le port 11211 :</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\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.memcached.MemcachedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n            <span class=\"s1\">&#39;172.19.26.240:11211&#39;</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;172.19.26.242:11211&#39;</span><span class=\"p\">,</span>\n        <span class=\"p\">]</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Dans l’exemple suivant, le cache est distribué sur des instances Memcached fonctionnant aux adresses IP 172.19.26.240 (port 11211), 172.19.26.242 (port 11212), and 172.19.26.244 (port 11213) :</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\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.memcached.MemcachedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n            <span class=\"s1\">&#39;172.19.26.240:11211&#39;</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;172.19.26.242:11212&#39;</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;172.19.26.244:11213&#39;</span><span class=\"p\">,</span>\n        <span class=\"p\">]</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Un dernier point au sujet de Memcached est que le cache basé sur la mémoire présente un désavantage : en raison du stockage en mémoire, les données du cache sont perdues si le serveur s’arrête. Il est clair que la mémoire n’est pas prévue pour contenir des données de manière permanente, il ne faut donc pas se baser sur du cache en mémoire comme seul stockage de données. Sans aucun doute, <em>aucun</em> des moteurs de cache de Django ne devrait être utilisé pour du stockage permanent, ils sont tous prévus pour être des solutions de mise en cache et non pour du stockage ; mais nous signalons cela ici car le cache basé sur la mémoire est particulièrement volatile.</p>\n</section>\n<section id=\"database-caching\">\n<span id=\"id4\"></span><h3>Cache en base de données<a class=\"heading-anchor\" href=\"#database-caching\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django peut stocker ses données mises en cache dans votre base de données. Cela fonctionne mieux si vous avez un serveur de base de données rapide et bien indexé.</p>\n<p>Pour utiliser une table de base de données comme cache :</p>\n<ul class=\"simple\">\n<li><p>Définissez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> à <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.cache.backends.db.DatabaseCache</span></code></p></li>\n<li><p>Pour <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a>, indiquez <code class=\"docutils literal notranslate\"><span class=\"pre\">tablename</span></code>, le nom de la table de base de données. Ce nom peut être librement choisi, pour autant qu’il corresponde à un nom de table valide qui n’est pas déjà utilisé dans votre base de données.</p></li>\n</ul>\n<p>Dans cet exemple, le nom de la table du cache est <code class=\"docutils literal notranslate\"><span class=\"pre\">my_cache_table</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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.db.DatabaseCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;my_cache_table&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<section id=\"creating-the-cache-table\">\n<h4>Création de la table du cache<a class=\"heading-anchor\" href=\"#creating-the-cache-table\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Avant d’utiliser le cache en base de données, vous devez créer la table du cache avec cette commande :</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\">python</span> <span class=\"n\">manage</span><span class=\"o\">.</span><span class=\"n\">py</span> <span class=\"n\">createcachetable</span>\n</code></pre></div>\n<p>Cela crée une table dans votre base de données qui est dans le format attendu par le système de cache de Django. Le nom de la table est extrait de <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a>.</p>\n<p>Si vous utilisez plusieurs caches en base de données, <a class=\"reference internal\" href=\"/fr/1.10/ref/django-admin/#django-admin-createcachetable\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">createcachetable</span></code></a> crée une table pour chaque cache.</p>\n<p>Si vous utilisez plusieurs bases de données, <a class=\"reference internal\" href=\"/fr/1.10/ref/django-admin/#django-admin-createcachetable\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">createcachetable</span></code></a> respecte la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">allow_migrate</span> <span class=\"pre\">()</span></code> de vos routeurs de base de données (voir ci-dessous).</p>\n<p>Comme <a class=\"reference internal\" href=\"/fr/1.10/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>, <a class=\"reference internal\" href=\"/fr/1.10/ref/django-admin/#django-admin-createcachetable\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">createcachetable</span></code></a> ne touchera pas à une table existante. Il ne fera que créer les tables manquantes.</p>\n<p>Pour afficher le code SQL qui serait exécuté plutôt que de l’exécuter réellement, utilisez l’option <a class=\"reference internal\" href=\"/fr/1.10/ref/django-admin/#cmdoption-createcachetable-dry-run\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">createcachetable</span> <span class=\"pre\">--dry-run</span></code></a>.</p>\n</section>\n<section id=\"multiple-databases\">\n<h4>Bases de données multiples<a class=\"heading-anchor\" href=\"#multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous utilisez le cache en base de données avec plusieurs bases de données, vous devrez également indiquer des instructions de routage pour la table de base de données du cache. Dans l’optique du routage, la table de base de données du cache apparaît en tant que modèle nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">CacheEntry</span></code> dans une application nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">django_cache</span></code>. Ce modèle n’est pas présent dans le cache des modèles, mais il est possible d’utiliser les détails du modèle dans un contexte de routage.</p>\n<p>Par exemple, le routeur suivant redirige toutes les opérations de lecture de cache vers <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_replica</span></code> et toutes les opérations d’écriture en cache vers <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_primary</span></code>. La table de cache ne sera synchronisée que vers <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_primary</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=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CacheRouter</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;A router to control all database cache operations&quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">db_for_read</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;All cache read operations go to the replica&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">app_label</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;django_cache&#39;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s1\">&#39;cache_replica&#39;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">db_for_write</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;All cache write operations go to primary&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">app_label</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;django_cache&#39;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s1\">&#39;cache_primary&#39;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">allow_migrate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">db</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">model_name</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;Only install the cache model on primary&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">app_label</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;django_cache&#39;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">db</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;cache_primary&#39;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n</code></pre></div>\n<p>Si vous n’indiquez aucune information de routage pour le modèle de cache en base de données, le moteur de cache utilise la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>.</p>\n<p>Naturellement, si vous n’utilisez pas le moteur de cache en base de données, il n’est pas nécessaire de fournir des instructions de routage pour le modèle de cache en base de données.</p>\n</section>\n</section>\n<section id=\"filesystem-caching\">\n<h3>Cache sur système de fichiers<a class=\"heading-anchor\" href=\"#filesystem-caching\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Le moteur de cache basé sur des fichiers sérialise et stocke chaque valeur de cache dans un fichier séparé. Pour utiliser ce moteur, définissez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> à <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django.core.cache.backends.filebased.FileBasedCache&quot;</span></code> et renseignez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a> avec un répertoire approprié. Par exemple, pour stocker vos données en mémoire cache dans <code class=\"docutils literal notranslate\"><span class=\"pre\">/var/tmp/django_cache</span></code>, utilisez ce paramètre :</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\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.filebased.FileBasedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;/var/tmp/django_cache&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Si vous êtes sur Windows, indiquez la lettre de lecteur au début du chemin, 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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.filebased.FileBasedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;c:/foo/bar&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Le chemin de répertoire doit être absolu, c’est-à-dire qu’il doit commencer à la racine du système de fichiers. La barre oblique en fin de chemin est facultative.</p>\n<p>Assurez-vous que le répertoire indiqué par ce réglage existe bel et bien et qu’il est accessible en lecture et écriture par l’utilisateur système avec lequel tourne votre serveur Web. Poursuivant l’exemple ci-dessus, si votre serveur tourne avec l’utilisateur <code class=\"docutils literal notranslate\"><span class=\"pre\">apache</span></code>, vérifiez que le répertoire <code class=\"docutils literal notranslate\"><span class=\"pre\">/var/tmp/django_cache</span></code> existe et qu’il est accessible en lecture et écriture par l’utilisateur <code class=\"docutils literal notranslate\"><span class=\"pre\">apache</span></code>.</p>\n</section>\n<section id=\"local-memory-caching\">\n<span id=\"id5\"></span><h3>Cache en mémoire locale<a class=\"heading-anchor\" href=\"#local-memory-caching\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il s’agit du cache par défaut s’il n’y en a pas un autre défini dans votre fichier de réglages. Si vous souhaitez obtenir les avantages de rapidité du cache en mémoire mais que vous n’avez pas la possibilité de faire fonctionner Memcached, considérez la possibilité d’utiliser le moteur de cache en mémoire locale. Ce cache est par processus (voir ci-dessous) et gère la concurrence entre fils d’exécution (thread-safe). Pour l’utiliser, définissez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> à <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;django.core.cache.backends.locmem.LocMemCache&quot;</span></code>. Par exemple :</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\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.locmem.LocMemCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;unique-snowflake&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Le réglage de cache <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a> est utilisé pour identifier les stockages individuels en mémoire. Si vous n’avez qu’un seul cache <code class=\"docutils literal notranslate\"><span class=\"pre\">locmem`</span></code>, vous pouvez omettre de configurer <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-LOCATION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOCATION</span></code></a>; Cependant, si vous avez plus d’un stockage en mémoire locale, vous devrez attribuer un nom à au moins l’un d’entre eux afin de pouvoir les distinguer.</p>\n<p>Notez que chaque processus aura sa propre instance de cache privée, ce qui signifie qu’il n’est pas possible de faire du cache inter-processus. Cela signifie évidemment aussi que le cache en mémoire locale n’est pas particulièrement efficace en mémoire, ce qui n’en fait pas un très bon choix en environnement de production. Mais il est pratique pour le développement.</p>\n</section>\n<section id=\"dummy-caching-for-development\">\n<h3>Pseudo-cache (pour le développement)<a class=\"heading-anchor\" href=\"#dummy-caching-for-development\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour terminer, Django fournit un « pseudo-cache » qui ne fait pas réellement de cache, mais qui ne fait qu’implémenter l’interface de cache sans action réelle.</p>\n<p>Il est utile dans le cas où un site utilise intensivement le cache en production dans différents endroits, mais que l’environnement de test ou de développement n’est pas censé exploiter le cache et que vous ne souhaitez pas changer le code pour distinguer les types d’environnement au cas par cas. Pour activer le pseudo-cache, définissez <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> 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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.dummy.DummyCache&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n</section>\n<section id=\"using-a-custom-cache-backend\">\n<h3>Utilisation d’un moteur de cache personnalisé<a class=\"heading-anchor\" href=\"#using-a-custom-cache-backend\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Bien que Django soit livré avec un certain nombre de moteurs de cache, il peut parfois être nécessaire de créer son propre moteur de cache. Pour utiliser un moteur de cache personnalisé avec Django, il s’agit d’indiquer le chemin d’importation Python dans la clé <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> du réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a>, 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=\"n\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;path.to.backend&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Si vous créez votre propre moteur, vous pouvez considérer les moteurs de cache standards comme les implémentations de référence. Le code se trouve dans le répertoire <code class=\"docutils literal notranslate\"><span class=\"pre\">django/core/cache/backends/</span></code> du code source de Django.</p>\n<p>Note : sans raison impérieuse, comme par exemple un hôte qui ne les prend pas en charge, il est recommandé de se restreindre aux moteurs de cache inclus dans Django. Ils sont intensivement testés et simples d’emploi.</p>\n</section>\n<section id=\"cache-arguments\">\n<span id=\"id6\"></span><h3>Paramètres de cache<a class=\"heading-anchor\" href=\"#cache-arguments\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Chaque moteur de cache accepte des paramètres supplémentaires pour contrôler le comportement du cache. Ces paramètres sont transmis sous la forme de clés supplémentaires dans le réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a>. Les paramètres valides sont les suivants :</p>\n<ul>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-TIMEOUT\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TIMEOUT</span></code></a>: le délai d’expiration du cache par défaut, en secondes. Ce paramètre contient <code class=\"docutils literal notranslate\"><span class=\"pre\">300</span></code> secondes (5 minutes) par défaut. Vous pouvez définir <code class=\"docutils literal notranslate\"><span class=\"pre\">TIMEOUT</span></code> à la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> de sorte que, par défaut, les clés de cache n’expirent jamais. Une valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">0</span></code> implique que les clés expirent immédiatement (dans les faits on « ne met pas en cache »).</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">OPTIONS</span></code></a>: toute option devant être transmise au moteur de cache. La liste des options valides dépend de chaque moteur et les moteurs s’appuyant sur une bibliothèque tierce transmettent directement ces options à la bibliothèque de cache sous-jacente.</p>\n<p>Les moteurs de cache implémentant leur propre stratégie de purge (« culling »), c’est-à-dire les moteurs <code class=\"docutils literal notranslate\"><span class=\"pre\">locmem</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">filesystem</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">database</span></code>, acceptent les options suivantes :</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">MAX_ENTRIES</span></code>: le nombre maximum d’éléments autorisés dans le cache avant que des valeurs plus anciennes ne soient supprimées. Ce paramètre vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">300</span></code> par défaut.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">CULL_FREQUENCY</span></code>: la quantité d’éléments effacés lorsque le nombre <code class=\"docutils literal notranslate\"><span class=\"pre\">MAX_ENTRIES</span></code> est atteint. Le taux effectif est <code class=\"docutils literal notranslate\"><span class=\"pre\">1</span> <span class=\"pre\">/</span> <span class=\"pre\">CULL_FREQUENCY</span></code>, il faut donc indiquer <code class=\"docutils literal notranslate\"><span class=\"pre\">2</span></code> dans <code class=\"docutils literal notranslate\"><span class=\"pre\">CULL_FREQUENCY</span></code> pour purger la moitié des éléments lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">MAX_ENTRIES</span></code> est atteint. Ce paramètre doit être un nombre entier, et sa valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">3</span></code>.</p>\n<p>Une valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">CULL_FREQUENCY</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">0</span></code> signifie que tout le cache est effacé lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">MAX_ENTRIES</span></code> est atteint. Sur certains moteurs (<code class=\"docutils literal notranslate\"><span class=\"pre\">database</span></code> en particulier), cela accélère <em>nettement</em> la purge du cache au dépend de davantage de défauts de cache.</p>\n</li>\n</ul>\n</li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-KEY_PREFIX\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">KEY_PREFIX</span></code></a>: une chaîne étant systématiquement incluse (en préfixe par défaut) dans toutes les clés de cache utilisées par le serveur Django.</p>\n<p>Consultez la <a class=\"reference internal\" href=\"#cache-key-prefixing\"><span class=\"std std-ref\">documentation du cache</span></a> pour plus d’informations.</p>\n</li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-VERSION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">VERSION</span></code></a>: le numéro de version par défaut des clés de cache générées par le serveur Django.</p>\n<p>Consultez la <a class=\"reference internal\" href=\"#cache-versioning\"><span class=\"std std-ref\">documentation du cache</span></a> pour plus d’informations.</p>\n</li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-KEY_FUNCTION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">KEY_FUNCTION</span></code></a>: une chaîne contenant un chemin pointé vers une fonction qui définit la manière de composer un préfixe, une version et une clé pour former une clé de cache finale.</p>\n<p>Consultez la <a class=\"reference internal\" href=\"#cache-key-transformation\"><span class=\"std std-ref\">documentation du cache</span></a> pour plus d’informations.</p>\n</li>\n</ul>\n<p>Dans cet exemple, un moteur basé sur le système de fichiers est configuré avec un délai d’expiration de 60 secondes et une capacité maximale de 1000 éléments :</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\">CACHES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;BACKEND&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.core.cache.backends.filebased.FileBasedCache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;LOCATION&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;/var/tmp/django_cache&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;TIMEOUT&#39;</span><span class=\"p\">:</span> <span class=\"mi\">60</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;MAX_ENTRIES&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1000</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Les paramètres non valables sont ignorés en silence, tout comme les valeurs non valides de paramètres connus.</p>\n</section>\n</section>\n<section id=\"the-per-site-cache\">\n<span id=\"id7\"></span><h2>Le cache « par site »<a class=\"heading-anchor\" href=\"#the-per-site-cache\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Une fois le cache configuré, la manière la plus simple d’utiliser le cache est de mettre en cache tout le site. Il s’agit alors d’ajouter <code class=\"docutils literal notranslate\"><span class=\"pre\">'django.middleware.cache.UpdateCacheMiddleware'</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">'django.middleware.cache.FetchFromCacheMiddleware'</span></code> au réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>, comme dans cet exemple :</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=\"s1\">&#39;django.middleware.cache.UpdateCacheMiddleware&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.middleware.common.CommonMiddleware&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.middleware.cache.FetchFromCacheMiddleware&#39;</span><span class=\"p\">,</span>\n<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>Non, il ne s’agit pas d’une erreur : l’intergiciel « update » doit bien figurer en premier dans la liste, et l’intergiciel « fetch » en dernier. Les détails sont quelque peu obscurs, mais vous pouvez consulter <a class=\"reference internal\" href=\"#order-of-middleware\">Ordre dans MIDDLEWARE</a> ci-dessous pour connaître toute l’histoire.</p>\n</aside>\n<p>Puis, ajoutez les réglages obligatoires suivants dans votre fichier de réglages Django :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_ALIAS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_ALIAS</span></code></a> – L’alias de cache à utiliser pour le stockage.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_SECONDS</span></code></a> – le nombre de secondes durant lequel chaque page doit être conservée en cache.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_KEY_PREFIX\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_KEY_PREFIX</span></code></a> – Si le cache est partagé par plusieurs sites utilisant la même installation de Django, définissez cette valeur au nom du site ou à un nom unique de cette instance de Django, afin d’éviter des collisions de clés. Indiquez une chaîne vide si cela ne vous concerne pas.</p></li>\n</ul>\n<p>L’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">FetchFromCacheMiddleware</span></code> met en mémoire cache les réponses GET et HEAD ayant le statut 200, pour autant que les en-têtes de requête et de réponse le permettent. Les réponses aux requêtes à une même URL ayant des paramètres de requête différents sont considérées comme des pages distinctes et sont mises en cache séparément. Cet intergiciel s’attend à ce que la réponse à une requête HEAD possède les mêmes en-têtes de réponse que la requête GET équivalente ; et dans ce cas, il peut renvoyer une réponse GET à partir du cache lors d’une requête HEAD.</p>\n<p>De plus, l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> définit automatiquement quelques en-têtes dans chaque réponse <a class=\"reference internal\" href=\"/fr/1.10/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>:</p>\n<ul class=\"simple\">\n<li><p>L’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Last-Modified</span></code> est défini à la date/heure courante lorsqu’une version fraîche (pas dans le cache) d’une page est demandée.</p></li>\n<li><p>L’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Expires</span></code> est défini à la date/heure courante additionnée de <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_SECONDS</span></code></a>.</p></li>\n<li><p>L’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Cache-Control</span></code> est défini à un âge maximal de la page, aussi selon le réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_SECONDS</span></code></a>.</p></li>\n</ul>\n<p>Voir <a class=\"reference internal\" href=\"/fr/1.10/topics/http/middleware/\"><span class=\"doc\">Intergiciels (« Middleware »)</span></a> pour plus d’informations sur les intergiciels.</p>\n<p>Si une vue définit son propre délai d’expiration de cache (par ex. avec une section <code class=\"docutils literal notranslate\"><span class=\"pre\">max-age</span></code> dans son en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Cache-Control</span></code>), la page sera mise en cache jusqu’à la fin de ce délai d’expiration, sans tenir compte du temps défini dans <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_SECONDS</span></code></a>. À l’aide des décorateurs de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.views.decorators.cache</span></code>, vous pouvez facilement définir le délai d’expiration d’une vue (par le décorateur <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">cache_control()</span></code></a>) ou désactiver la mise en cache d’une vue (par le décorateur <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.cache.never_cache\" title=\"django.views.decorators.cache.never_cache\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">never_cache()</span></code></a>). Consultez la section <a class=\"reference internal\" href=\"#controlling-cache-using-other-headers\">utilisation d’autres en-têtes</a> pour en savoir plus sur ces décorateurs.</p>\n<p id=\"i18n-cache-key\">Si <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-USE_I18N\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">USE_I18N</span></code></a> est défini à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, la clé de cache générée inclut le nom de la <a class=\"reference internal\" href=\"/fr/1.10/topics/i18n/#term-language-code\"><span class=\"xref std std-term\">langue</span></a> active, voir aussi <a class=\"reference internal\" href=\"/fr/1.10/topics/i18n/translation/#how-django-discovers-language-preference\"><span class=\"std std-ref\">Processus de découverte de la préférence de langue par Django</span></a>). Cela permet de facilement mettre en cache des sites multilingues sans devoir créer soi-même les clés de cache.</p>\n<p>Les clés de cache incluent également la <a class=\"reference internal\" href=\"/fr/1.10/topics/i18n/#term-language-code\"><span class=\"xref std std-term\">langue</span></a> active lorsque  <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-USE_L10N\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">USE_L10N</span></code></a> est défini à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> ainsi que le <a class=\"reference internal\" href=\"/fr/1.10/topics/i18n/timezones/#default-current-time-zone\"><span class=\"std std-ref\">fuseau horaire actuel</span></a> lorsque <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-USE_TZ\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">USE_TZ</span></code></a> est défini à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n</section>\n<section id=\"the-per-view-cache\">\n<h2>Le cache par vue<a class=\"heading-anchor\" href=\"#the-per-view-cache\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.cache.cache_page\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.views.decorators.cache.</span></span><span class=\"sig-name descname\"><span class=\"pre\">cache_page</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.cache.cache_page\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Une manière plus fine d’utiliser l’infrastructure de cache est de mettre en cache le résultat de vues individuelles. <code class=\"docutils literal notranslate\"><span class=\"pre\">django.views.decorators.cache</span></code> définit un décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</span></code> qui se charge de mettre en cache la réponse de la vue. Il est simple à mettre en place :</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.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache_page</span>\n\n<span class=\"nd\">@cache_page</span><span class=\"p\">(</span><span class=\"mi\">60</span> <span class=\"o\">*</span> <span class=\"mi\">15</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</span></code> accepte un seul paramètre : le délai d’expiration du cache en secondes. Dans l’exemple ci-dessus, le résultat de la vue <code class=\"docutils literal notranslate\"><span class=\"pre\">my_view()</span></code> reste en cache pendant 15 minutes (remarquez que nous avons écrit <code class=\"docutils literal notranslate\"><span class=\"pre\">60</span> <span class=\"pre\">*</span> <span class=\"pre\">15</span></code> par souci de lisibilité, le résultat donne <code class=\"docutils literal notranslate\"><span class=\"pre\">900</span></code>, c’est-à-dire 15 minutes multipliées par 60 secondes).</p>\n<p>Le cache par vue, comme le cache par site, construit ses clés d’après les URL. Si des URL différentes pointent vers la même vue, chaque URL aura son propre cache. En reprenant l’exemple <code class=\"docutils literal notranslate\"><span class=\"pre\">my_view</span></code>, si votre configuration d’URL 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=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^foo/([0-9]{1,2})/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">my_view</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>alors les requêtes vers <code class=\"docutils literal notranslate\"><span class=\"pre\">/foo/1/</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">/foo/23/</span></code> seront mises en cache séparément, comme prévu. Dès qu’une des URL a été accédée (par ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">/foo/23/</span></code>), les requêtes suivantes à cette même URL utiliseront le cache.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</span></code> accepte également un paramètre nommé facultatif, <code class=\"docutils literal notranslate\"><span class=\"pre\">cache</span></code>, qui indique au décorateur d’utiliser un cache spécifique (parmi ceux du réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a>) lors de la mise en cache des résultats de la vue. Par défaut, c’est le cache <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> qui est utilisé, mais vous pouvez indiquer le cache que vous souhaitez :</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=\"nd\">@cache_page</span><span class=\"p\">(</span><span class=\"mi\">60</span> <span class=\"o\">*</span> <span class=\"mi\">15</span><span class=\"p\">,</span> <span class=\"n\">cache</span><span class=\"o\">=</span><span class=\"s2\">&quot;special_cache&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Il est aussi possible de surcharger le préfixe de cache par vue. <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</span></code> accepte un paramètre nommé facultatif, <code class=\"docutils literal notranslate\"><span class=\"pre\">key_prefix</span></code>, qui joue le même rôle que le réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_KEY_PREFIX\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_KEY_PREFIX</span></code></a> pour l’intergiciel. Il peut être utilisé comme suit :</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=\"nd\">@cache_page</span><span class=\"p\">(</span><span class=\"mi\">60</span> <span class=\"o\">*</span> <span class=\"mi\">15</span><span class=\"p\">,</span> <span class=\"n\">key_prefix</span><span class=\"o\">=</span><span class=\"s2\">&quot;site1&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">key_prefix</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">cache</span></code> peuvent être tous deux spécifiés. Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">key_prefix</span></code> et la clé <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-KEY_PREFIX\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">KEY_PREFIX</span></code></a> du réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a> sont combinés.</p>\n<section id=\"specifying-per-view-cache-in-the-urlconf\">\n<h3>Utilisation du cache par vue dans la configuration d’URL<a class=\"heading-anchor\" href=\"#specifying-per-view-cache-in-the-urlconf\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les exemples de la section précédente ont figé dans le code le fait que la vue est mise en cache, car <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</span></code> modifie la fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">my_view</span></code> sur place. Cette approche lie la vue au système de cache, ce qui n’est pas idéal pour plusieurs raisons. Par exemple, il est possible que les vues puissent être réutilisées pour un autre site sans cache, ou peut-être qu’à un moment donné les vues seront mises à disposition d’autres personnes qui voudront les utiliser sans cache. La solution à ces problèmes est de définir le cache par vue dans la configuration d’URL plutôt qu’autour des fonctions de vue elles-mêmes.</p>\n<p>C’est simple à faire : il suffit d’entourer la fonction de vue par <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</span></code> lorsque vous la mentionnez dans la configuration d’URL. Voici la configuration que nous avons déjà vue précédemment :</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\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^foo/([0-9]{1,2})/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">my_view</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Et la même chose, avec <code class=\"docutils literal notranslate\"><span class=\"pre\">my_view</span></code> entourée par <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_page</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.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache_page</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^foo/([0-9]{1,2})/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">cache_page</span><span class=\"p\">(</span><span class=\"mi\">60</span> <span class=\"o\">*</span> <span class=\"mi\">15</span><span class=\"p\">)(</span><span class=\"n\">my_view</span><span class=\"p\">)),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"template-fragment-caching\">\n<span id=\"std-templatetag-cache\"></span><h2>Cache de gabarits partiels<a class=\"heading-anchor\" href=\"#template-fragment-caching\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si vous recherchez encore plus de contrôle, il est encore possible de mettre en cache des bouts de gabarits avec la balise de gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">cache</span></code>. Pour que vos gabarits aient accès à cette balise, placez <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">cache</span> <span class=\"pre\">%}</span></code> au début du gabarit.</p>\n<p>La balise de gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">cache</span> <span class=\"pre\">%}</span></code> met en cache le contenu du bloc pour un temps donné. Il accepte au moins deux paramètres : le délai d’expiration de cache en secondes et le nom à donner au fragment de cache. Le nom est accepté tel quel, n’utilisez pas de variable. Par exemple :</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\">load</span> <span class=\"nv\">cache</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">cache</span> <span class=\"m\">500</span> <span class=\"nv\">sidebar</span> <span class=\"cp\">%}</span>\n    .. sidebar ..\n<span class=\"cp\">{%</span> <span class=\"k\">endcache</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Il peut arriver que vous souhaitiez mettre en cache plusieurs copies d’un fragment en fonction de certaines données dynamiques apparaissant dans le fragment. Par exemple, la barre latérale de l’exemple précédent pourrait être mise en cache séparément pour chaque utilisateur du site. Cela se fait en passant des paramètres supplémentaires à la balise de gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">cache</span> <span class=\"pre\">%}</span></code> afin d’identifier le fragment de cache de manière unique :</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\">load</span> <span class=\"nv\">cache</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">cache</span> <span class=\"m\">500</span> <span class=\"nv\">sidebar</span> <span class=\"nv\">request.user.username</span> <span class=\"cp\">%}</span>\n    .. sidebar for logged in user ..\n<span class=\"cp\">{%</span> <span class=\"k\">endcache</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Il est tout à fait correct d’indiquer plus d’un paramètre pour identifier le fragment. Il suffit de transmettre autant de paramètres que nécessaire à <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">cache</span> <span class=\"pre\">%}</span></code>.</p>\n<p>Quand <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-USE_I18N\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">USE_I18N</span></code></a> est défini à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, le cache intergiciel par site <a class=\"reference internal\" href=\"#i18n-cache-key\"><span class=\"std std-ref\">respecte la langue active</span></a>. Pour la balise de gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">cache</span></code>, il est possible d’utiliser l’une des <a class=\"reference internal\" href=\"/fr/1.10/topics/i18n/translation/#template-translation-vars\"><span class=\"std std-ref\">variables spécifiques aux traductions</span></a> disponibles dans les gabarits pour obtenir le même résultat :</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\">load</span> <span class=\"nv\">i18n</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">load</span> <span class=\"nv\">cache</span> <span class=\"cp\">%}</span>\n\n<span class=\"cp\">{%</span> <span class=\"k\">get_current_language</span> <span class=\"k\">as</span> <span class=\"nv\">LANGUAGE_CODE</span> <span class=\"cp\">%}</span>\n\n<span class=\"cp\">{%</span> <span class=\"k\">cache</span> <span class=\"m\">600</span> <span class=\"nv\">welcome</span> <span class=\"nv\">LANGUAGE_CODE</span> <span class=\"cp\">%}</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">trans</span> <span class=\"s2\">&quot;Welcome to example.com&quot;</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endcache</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Le délai d’expiration de cache peut être une variable de gabarit, pour autant que la variable de gabarit corresponde à un nombre entier. Par exemple, si la variable de gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">my_timeout</span></code> contient la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">600</span></code>, les deux exemples suivants sont alors équivalents :</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\">cache</span> <span class=\"m\">600</span> <span class=\"nv\">sidebar</span> <span class=\"cp\">%}</span> ... <span class=\"cp\">{%</span> <span class=\"k\">endcache</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">cache</span> <span class=\"nv\">my_timeout</span> <span class=\"nv\">sidebar</span> <span class=\"cp\">%}</span> ... <span class=\"cp\">{%</span> <span class=\"k\">endcache</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Cette fonctionnalité est utile pour éviter les répétitions dans les gabarits. Vous pouvez définir le délai d’expiration dans une variable à un seul endroit, puis simplement réutiliser cette valeur.</p>\n<p>Par défaut, la balise <code class=\"docutils literal notranslate\"><span class=\"pre\">cache</span></code> va essayer d’utiliser le cache appelé « template_fragments ». Si aucun cache de ce type n’existe, il se replie sur l’utilisation du cache par défaut. Vous pouvez définir un moteur de cache alternatif à utiliser au moyen du paramètre nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code>, qui doit être le dernier paramètre de la balise.</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\">cache</span> <span class=\"m\">300</span> <span class=\"nv\">local-thing</span> <span class=\"p\">...</span>  <span class=\"nv\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;localcache&quot;</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>L’indication d’un nom de cache qui n’est pas configuré est considéré comme une erreur.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.core.cache.utils.make_template_fragment_key\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.core.cache.utils.</span></span><span class=\"sig-name descname\"><span class=\"pre\">make_template_fragment_key</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fragment_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">vary_on</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.cache.utils.make_template_fragment_key\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Si vous souhaitez obtenir la clé de cache utilisée pour un fragment en cache, vous pouvez utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">make_template_fragment_key</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">fragment_name</span></code> est comme le second paramètre de la balise de gabarit <code class=\"docutils literal notranslate\"><span class=\"pre\">cache</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">vary_on</span></code> est une liste de tous les paramètres supplémentaires transmis à la balise. Cette fonction peut être utile pour invalider ou écraser un élément du cache, par exemple :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.cache.utils</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">make_template_fragment_key</span>\n<span class=\"go\"># cache key for {% cache 500 sidebar username %}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">key</span> <span class=\"o\">=</span> <span class=\"n\">make_template_fragment_key</span><span class=\"p\">(</span><span class=\"s1\">&#39;sidebar&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">username</span><span class=\"p\">])</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">)</span> <span class=\"c1\"># invalidates cached template fragment</span>\n</code></pre></div>\n</section>\n<section id=\"the-low-level-cache-api\">\n<h2>L’API de cache de bas niveau<a class=\"heading-anchor\" href=\"#the-low-level-cache-api\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Dans certains cas, la mise en cache d’une page entière ne donne pas d’avantage significatif et peut même se révéler totalement inutile.</p>\n<p>Imaginons par exemple que votre site contienne une vue dont les résultats dépendent de plusieurs requêtes coûteuses dont les résultats changent à des moments différents. Dans ce cas, il ne serait pas idéal d’utiliser la mise en cache de pages entières telles que l’offrent les stratégies de cache par site ou par vue, parce qu’il n’est pas souhaitable de mettre en cache la totalité du résultat (étant donné que certaines données changent souvent), mais il reste intéressant de mettre en cache les résultats qui changent rarement.</p>\n<p>Dans de telles situations, Django expose une API de cache simple et de bas niveau. Vous pouvez utiliser cette API pour stocker des objets dans le cache avec la granularité de votre choix. Vous pouvez placer dans ce cache tout objet Python pouvant être sérialisée par <code class=\"docutils literal notranslate\"><span class=\"pre\">pickle</span></code>: chaînes, dictionnaires, listes d’objets de modèle, etc. (la plupart des objets Python courants peuvent être ainsi sérialisés, référez-vous à la documentation de Python pour plus d’informations sur la sérialisation <code class=\"docutils literal notranslate\"><span class=\"pre\">pickle</span></code>).</p>\n<section id=\"accessing-the-cache\">\n<h3>Accès au cache<a class=\"heading-anchor\" href=\"#accessing-the-cache\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py data\">\n<dt class=\"sig sig-object py\" id=\"django.core.cache.caches\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.core.cache.</span></span><span class=\"sig-name descname\"><span class=\"pre\">caches</span></span><a class=\"heading-anchor\" href=\"#django.core.cache.caches\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Vous pouvez accéder aux caches configurés dans le réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a> par un objet de type dictionnaire : <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.cache.caches</span></code>. Les requêtes successives du même alias dans le même fil d’exécution renvoient le même objet.</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">caches</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache1</span> <span class=\"o\">=</span> <span class=\"n\">caches</span><span class=\"p\">[</span><span class=\"s1\">&#39;myalias&#39;</span><span class=\"p\">]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache2</span> <span class=\"o\">=</span> <span class=\"n\">caches</span><span class=\"p\">[</span><span class=\"s1\">&#39;myalias&#39;</span><span class=\"p\">]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache1</span> <span class=\"ow\">is</span> <span class=\"n\">cache2</span>\n<span class=\"go\">True</span>\n</code></pre></div>\n<p>Si l’alias indiqué n’existe pas, une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">InvalidCacheBackendError</span></code> est générée.</p>\n<p>Pour respecter la concurrence des fils d’exécution, une instance différente du moteur de cache est renvoyée pour chaque fil d’exécution.</p>\n</dd></dl>\n\n<dl class=\"py data\">\n<dt class=\"sig sig-object py\" id=\"django.core.cache.cache\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.core.cache.</span></span><span class=\"sig-name descname\"><span class=\"pre\">cache</span></span><a class=\"heading-anchor\" href=\"#django.core.cache.cache\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>En raccourci, le cache par défaut est disponible dans <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.cache.cache</span></code>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache</span>\n</code></pre></div>\n<p>Cet objet est équivalent à <code class=\"docutils literal notranslate\"><span class=\"pre\">caches['default']</span></code>.</p>\n</dd></dl>\n\n</section>\n<section id=\"basic-usage\">\n<h3>Utilisation de base<a class=\"heading-anchor\" href=\"#basic-usage\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’interface de base est <code class=\"docutils literal notranslate\"><span class=\"pre\">set(key,</span> <span class=\"pre\">value,</span> <span class=\"pre\">timeout)</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">get(key)</span></code>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;hello, world!&#39;</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;hello, world!&#39;</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">key</span></code> doit être de type <code class=\"docutils literal notranslate\"><span class=\"pre\">str</span></code> (ou <code class=\"docutils literal notranslate\"><span class=\"pre\">unicode</span></code> avec Python 2), et <code class=\"docutils literal notranslate\"><span class=\"pre\">value</span></code> peut être n’importe quel objet Python sérialisé par « pickle ».</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">timeout</span></code> est optionnel et est par défaut à la même valeur que le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">timeout</span></code> du backend approprié défini dans le réglage de <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a> (expliqué ci-dessus). Il correspond au nombre de secondes pendant lesquelles la valeur doit être stockée dans le cache. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">timeout</span></code> a la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> la valeur reste en cache pour toujours. Un <code class=\"docutils literal notranslate\"><span class=\"pre\">timeout</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">0</span></code> ne met pas en cache la valeur.</p>\n<p>Si l’objet n’existe pas dans le cache, <code class=\"docutils literal notranslate\"><span class=\"pre\">cache.get()</span></code> renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Wait 30 seconds for &#39;my_key&#39; to expire...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">None</span>\n</code></pre></div>\n<p>Nous déconseillons de stocker la valeur littérale <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> dans le cache, car il ne sera pas possible de distinguer entre votre valeur stockée <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> et un défaut de cache signifié par une valeur de renvoi <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">cache.get()</span></code> accepte un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>. Ceci permet d’indiquer la valeur à renvoyer si l’objet n’existe pas dans le cache :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;has expired&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;has expired&#39;</span>\n</code></pre></div>\n<p>Pour ajouter une clé dans le seul cas où elle n’existe pas encore, utilisez la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">add()</span></code>. Elle accepte les mêmes paramètres que <code class=\"docutils literal notranslate\"><span class=\"pre\">set()</span></code>, mais elle n’essaie pas de mettre à jour le cache si la clé indiquée est déjà présente :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;add_key&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Initial value&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"s1\">&#39;add_key&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;New value&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;add_key&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;Initial value&#39;</span>\n</code></pre></div>\n<p>Si vous avez besoin de savoir si <code class=\"docutils literal notranslate\"><span class=\"pre\">add()</span></code> a bien stocké une valeur dans le cache, vous pouvez consulter la valeur renvoyée : <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si la valeur a été stockée et <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> dans le cas contraire.</p>\n<p>Si vous souhaitez obtenir la valeur d’une clé ou définir cette valeur si la clé ne se trouve pas dans le cache, il existe une méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_or_set()</span></code>. Elle accepte les mêmes paramètres que <code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> mais la valeur par défaut est définie comme nouvelle valeur de cette clé dans le cache, plutôt que d’être simplement renvoyée :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_new_key&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># returns None</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get_or_set</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_new_key&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;my new value&#39;</span><span class=\"p\">,</span> <span class=\"mi\">100</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;my new value&#39;</span>\n</code></pre></div>\n<p>Vous pouvez également passer n’importe quel objet exécutable comme valeur <em>par défaut</em> :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get_or_set</span><span class=\"p\">(</span><span class=\"s1\">&#39;some-timestamp-key&#39;</span><span class=\"p\">,</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">)</span>\n<span class=\"go\">datetime.datetime(2014, 12, 11, 0, 15, 49, 457920)</span>\n</code></pre></div>\n<aside class=\"version-note version-changed\" data-version=\"1.9\">\n<p class=\"version-note-title\">Changed in Django 1.9</p><p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_or_set()</span></code> a été ajoutée.</p>\n</aside>\n<p>Il existe aussi une interface <code class=\"docutils literal notranslate\"><span class=\"pre\">get_many()</span></code> qui n’interroge le cache qu’une seule fois. <code class=\"docutils literal notranslate\"><span class=\"pre\">get_many()</span></code> renvoie un dictionnaire contenant toutes les clés demandées qui existent réellement dans le cache (et qui n’ont pas expiré) :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;c&#39;</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get_many</span><span class=\"p\">([</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;b&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;c&#39;</span><span class=\"p\">])</span>\n<span class=\"go\">{&#39;a&#39;: 1, &#39;b&#39;: 2, &#39;c&#39;: 3}</span>\n</code></pre></div>\n<p>Pour définir plusieurs valeurs de manière plus efficace, utilisez <code class=\"docutils literal notranslate\"><span class=\"pre\">set_many()</span></code> pour transmettre un dictionnaire de paires clé-valeur :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set_many</span><span class=\"p\">({</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"s1\">&#39;b&#39;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s1\">&#39;c&#39;</span><span class=\"p\">:</span> <span class=\"mi\">3</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get_many</span><span class=\"p\">([</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;b&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;c&#39;</span><span class=\"p\">])</span>\n<span class=\"go\">{&#39;a&#39;: 1, &#39;b&#39;: 2, &#39;c&#39;: 3}</span>\n</code></pre></div>\n<p>Tout comme <code class=\"docutils literal notranslate\"><span class=\"pre\">cache.set()</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">set_many()</span></code> accepte un paramètre facultatif <code class=\"docutils literal notranslate\"><span class=\"pre\">timeout</span></code> (délai d’expiration).</p>\n<p>Vous pouvez supprimer explicitement des clés avec <code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code>. C’est une façon simple d’effacer le cache pour un objet particulier :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">(</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous voulez effacer plusieurs clés en une seule opération, <code class=\"docutils literal notranslate\"><span class=\"pre\">delete_many()</span></code> accepte une liste de clés à effacer :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">delete_many</span><span class=\"p\">([</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;b&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;c&#39;</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>Pour finir, si vous voulez effacer toutes les clés du cache, utilisez <code class=\"docutils literal notranslate\"><span class=\"pre\">cache.clear()</span></code>. Mais soyez prudent ; <code class=\"docutils literal notranslate\"><span class=\"pre\">clear()</span></code> efface <em>tout</em> ce qui se trouve dans le cache, et pas seulement les clés définies par votre application :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">clear</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Vous pouvez aussi incrémenter ou décrémenter une clé existante au moyen des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">incr()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">decr()</span></code>, respectivement. Par défaut, l’incrément des valeurs de cache existantes est de 1. D’autre valeurs d’incrément peuvent être fournies en indiquant un paramètre lors de l’appel aux méthodes correspondantes. Une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">ValueError</span></code> est générée si vous essayez d’incrémenter ou de décrémenter une clé de cache non existante :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;num&#39;</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">incr</span><span class=\"p\">(</span><span class=\"s1\">&#39;num&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">incr</span><span class=\"p\">(</span><span class=\"s1\">&#39;num&#39;</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)</span>\n<span class=\"go\">12</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">decr</span><span class=\"p\">(</span><span class=\"s1\">&#39;num&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">11</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">decr</span><span class=\"p\">(</span><span class=\"s1\">&#39;num&#39;</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)</span>\n<span class=\"go\">6</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>L’atomicité des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">incr()</span></code>/<code class=\"docutils literal notranslate\"><span class=\"pre\">decr()</span></code> n’est pas garantie. Pour les moteurs qui peuvent garantir l’atomicité de l’incrémentation ou de la décrémentation (en particulier le moteur <code class=\"docutils literal notranslate\"><span class=\"pre\">memcached</span></code>), les opérations seront effectivement atomiques. Cependant, si le moteur ne contient pas d’opération d’incrémentation ou de décrémentation native, la fonctionnalité sera implémentée en deux temps par une opération de lecture suivie d’une opération de mise à jour.</p>\n</aside>\n<p>Vous pouvez fermer la connexion au cache avec <code class=\"docutils literal notranslate\"><span class=\"pre\">close()</span></code> si le moteur de cache prend en charge cette opération.</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=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">close</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>Pour les caches qui n’implémentent pas la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">close</span></code>, il s’agit d’une opération blanche.</p>\n</aside>\n</section>\n<section id=\"cache-key-prefixing\">\n<span id=\"id9\"></span><h3>Préfixe de clés de cache<a class=\"heading-anchor\" href=\"#cache-key-prefixing\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si une instance de cache est partagée entre plusieurs serveurs ou entre l’environnement de production et de développement, il est possible que des données mises en cache par un serveur soient lues par un autre serveur. Si le format des données mises en cache est différent d’un serveur à l’autre, cela peut conduire à des problèmes très difficiles à diagnostiquer.</p>\n<p>Pour éviter cela, Django offre la possibilité de préfixer toutes les clés de cache utilisées par un serveur. Pour chaque clé de cache enregistrée ou lue, Django préfixe automatiquement la clé de cache par la valeur du réglage de cache <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-KEY_PREFIX\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">KEY_PREFIX</span></code></a>.</p>\n<p>En prenant soin de définir des valeurs <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-KEY_PREFIX\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">KEY_PREFIX</span></code></a> différentes pour chaque instance de Django, vous pouvez vous assurer qu’il n’y aura pas de collisions de valeurs de cache.</p>\n</section>\n<section id=\"cache-versioning\">\n<span id=\"id10\"></span><h3>Versions dans le cache<a class=\"heading-anchor\" href=\"#cache-versioning\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsque vous modifiez du code utilisant des valeurs en cache, il peut être nécessaire de purger toutes les valeurs en cache. La manière la plus simple de le faire est d’effacer tout le cache, mais cela peut aussi effacer des valeurs en cache qui resteraient valides et utiles.</p>\n<p>Django met à disposition une façon plus subtile de cibler certaines valeurs de cache. Le système de cache de Django dispose d’un identifiant de version global défini dans le réglage de cache <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-VERSION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">VERSION</span></code></a>. La valeur de ce réglage est automatiquement combinée au préfixe de cache et à la clé de cache fournie par l’utilisateur pour obtenir la clé de cache finale.</p>\n<p>Par défaut, toute lecture de clé inclut automatiquement la version de clé de cache par défaut du site. Cependant, les fonctions de cache primitives proposent toutes un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">version</span></code>, afin de pouvoir indiquer une version de clé de cache particulière, que ce soit en lecture ou en écriture. Par exemple :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Set version 2 of a cache key</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">set</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;hello world!&#39;</span><span class=\"p\">,</span> <span class=\"n\">version</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Get the default version (assuming version=1)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">None</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Get version 2 of the same key</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">,</span> <span class=\"n\">version</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;hello world!&#39;</span>\n</code></pre></div>\n<p>La version d’une clé particulière peut être incrémentée ou décrémentée par les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">incr_version()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">decr_version()</span></code>. Cela permet de mettre à jour des clés spécifiques à une nouvelle version sans toucher aux autres clés. En poursuivant l’exemple précédent :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Increment the version of &#39;my_key&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">incr_version</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># The default version still isn&#39;t available</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">None</span>\n<span class=\"go\"># Version 2 isn&#39;t available, either</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">,</span> <span class=\"n\">version</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"go\">None</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># But version 3 *is* available</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">cache</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_key&#39;</span><span class=\"p\">,</span> <span class=\"n\">version</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;hello world!&#39;</span>\n</code></pre></div>\n</section>\n<section id=\"cache-key-transformation\">\n<span id=\"id11\"></span><h3>Transformation de clé de cache<a class=\"heading-anchor\" href=\"#cache-key-transformation\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Comme expliqué dans les deux précédentes sections, la clé de cache indiquée par un utilisateur n’est pas employée telle quelle – elle est combinée au préfixe de cache et à la version de clé pour composer une clé de cache finale. Par défaut, les trois parties sont combinées par des deux-points pour produire la clé finale :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">make_key</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">key_prefix</span><span class=\"p\">,</span> <span class=\"n\">version</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"s1\">&#39;:&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"n\">key_prefix</span><span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">version</span><span class=\"p\">),</span> <span class=\"n\">key</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>Si vous souhaitez combiner les parties d’une autre manière ou appliquer un autre traitement à la clé finale (par ex. en produisant une empreinte numérique des parties de la clé), vous pouvez définir une fonction de clé personnalisée.</p>\n<p>Le réglage de cache <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-KEY_FUNCTION\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">KEY_FUNCTION</span></code></a> indique un chemin en syntaxe pointée vers une fonction correspondant au prototype de <code class=\"docutils literal notranslate\"><span class=\"pre\">make_key()</span></code> (voir ci-dessus). Lorsqu’elle est définie, cette fonction de clé personnalisée sera utilisée en lieu et place de la fonction par défaut de combinaison de clé.</p>\n</section>\n<section id=\"cache-key-warnings\">\n<h3>Avertissements de clé de cache<a class=\"heading-anchor\" href=\"#cache-key-warnings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Memcached, le moteur de cache le plus souvent utilisé en production, n’autorise pas de clés de cache plus longues que 250 caractères ou qui contient des espaces ou des caractères de contrôle. De telles clés génèrent des exceptions. Pour promouvoir du code compatible entre caches et minimiser les mauvaises surprises, les autres moteurs de cache intégrés génèrent un avertissement (<code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.cache.backends.base.CacheKeyWarning</span></code>) si un nom de clé produirait une erreur avec <code class=\"docutils literal notranslate\"><span class=\"pre\">memcached</span></code>.</p>\n<p>Si vous utilisez un moteur de cache en production qui accepte un plus large éventail de clés (moteur personnalisé ou l’un des moteurs intégrés autres que memcached) et que vous ne voulez par être dérangé par les avertissements <code class=\"docutils literal notranslate\"><span class=\"pre\">CacheKeyWarning</span></code>, vous pouvez les masquer par ce code placé dans le module <code class=\"docutils literal notranslate\"><span class=\"pre\">management</span></code> de l’une des applications dans <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">warnings</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">CacheKeyWarning</span>\n\n<span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">simplefilter</span><span class=\"p\">(</span><span class=\"s2\">&quot;ignore&quot;</span><span class=\"p\">,</span> <span class=\"n\">CacheKeyWarning</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous préférez plutôt définir une logique de validation de clé personnalisée pour l’un des moteurs intégrés, vous pouvez créer une sous-classe qui ne surcharge que la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">validate_key</span></code> et suivre les instructions données dans <a class=\"reference internal\" href=\"#using-a-custom-cache-backend\">utilisation d’un moteur de cache personnalisé</a>. Par exemple, pour faire cela avec le moteur <code class=\"docutils literal notranslate\"><span class=\"pre\">locmem</span></code>, placez ce code dans un module :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.cache.backends.locmem</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">LocMemCache</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomLocMemCache</span><span class=\"p\">(</span><span class=\"n\">LocMemCache</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">validate_key</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;Custom validation, raising exceptions or warnings as needed.&quot;&quot;&quot;</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>…et utilisez le chemin Python pointé vers cette classe dans la partie <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES-BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">BACKEND</span></code></a> de votre réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a>.</p>\n</section>\n</section>\n<section id=\"downstream-caches\">\n<h2>Caches amonts<a class=\"heading-anchor\" href=\"#downstream-caches\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Jusqu’ici, ce document s’est concentré sur le cache de vos <em>propres</em> données. Mais dans le cadre du développement Web, un autre type de cache doit être considéré : le cache effectué par des caches « amonts ». Ce sont des systèmes qui mettent des pages en cache pour les utilisateurs avant même que les requêtes n’atteignent votre serveur Web.</p>\n<p>Voici quelques exemples de caches amonts :</p>\n<ul class=\"simple\">\n<li><p>Votre fournisseur de services Internet (ISP) peut mettre certaines pages en cache, donc en demandant une page à l’adresse <a class=\"reference external\" href=\"https://example.com/\">https://example.com/</a>, vous recevez la page de la part de votre fournisseur sans que la requête n’ait atteint directement example.com. Les mainteneurs de example.com n’ont pas conscience de ce processus de cache. Le fournisseur se place entre votre navigateur Web et le serveur example.com et se charge du cache de manière transparente.</p></li>\n<li><p>Votre site Web Django peut se trouver derrière un <em>cache mandataire</em> tel que Squid (<a class=\"reference external\" href=\"http://www.squid-cache.org/\">http://www.squid-cache.org/</a>), qui met des pages en cache pour améliorer les performances du réseau. Dans ce cas, chaque requête est d’abord traitée par le serveur mandataire et n’est transmise à votre application que s’il le juge nécessaire.</p></li>\n<li><p>Votre navigateur Web met aussi des pages en cache. Si une page Web envoie des en-têtes appropriés, le navigateur utilise la copie d’une page dans le cache local pour toute nouvelle requête vers cette même page, sans même redemander la page Web au serveur pour savoir si elle a changé.</p></li>\n</ul>\n<p>Les caches amonts améliorent bien les performances, mais il y a un risque : de nombreuses pages Web produisent du contenu différent selon la personne authentifiée ou selon d’autres paramètres, et donc des systèmes qui mettent aveuglément des pages en cache en ne se basant que sur l’URL pourraient exposer des données incorrectes ou sensibles à tout visiteur consultant ces pages.</p>\n<p>Par exemple, supposons que vous gériez un système de messagerie Web ; le contenu de la page « boîte de réception » dépend bien évidemment de l’utilisateur connecté. Si un fournisseur d’accès se met à mettre en cache votre site sans précaution, le premier utilisateur se connectant par l’intermédiaire de ce fournisseur verrait sa propre page de la boîte de réception placée dans le cache et à disposition des visiteurs suivants du site. Ce n’est pas sympa du tout.</p>\n<p>Heureusement, HTTP fournit une solution à ce problème. Il existe un certain nombre d’en-têtes HTTP indiquant aux caches amonts de différencier les contenus en cache selon certaines variables précises et d’indiquer aux mécanismes de cache de ne pas mettre en cache certaines pages. Nous allons examiner certains de ces en-têtes dans les sections qui suivent.</p>\n</section>\n<section id=\"using-vary-headers\">\n<span id=\"id12\"></span><h2>Utilisation des en-têtes <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code><a class=\"heading-anchor\" href=\"#using-vary-headers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>L’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code> définit quels en-têtes de requête un cache doit prendre en considération pour générer sa clé de cache. Par exemple, si le contenu d’une page Web dépend de la préférence de langue d’un utilisateur, on dit que la page « varie en fonction de la langue » (vary on language).</p>\n<p>Par défaut, le système de cache de Django crée ses clés de cache en utilisant l’URL complète de la requête, par exemple <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;https://www.example.com/stories/2005/?order_by=author&quot;</span></code>. Cela signifie que chaque requête vers cette URL utilisera la même version en cache, quels que soient les différences du client (« user-agent ») tels que ses cookies ou préférences de langue. Cependant, si cette page produit du contenu différent en fonction de certaines différences dans les en-têtes de la requête, tels qu’un cookie, une langue, une signature de client, etc. il est alors nécessaire d’utiliser l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code> pour signifier aux mécanismes de cache que le contenu de la page dépend de ces éléments.</p>\n<p>Pour faire cela avec Django, utilisez le décorateur de vue bien pratique <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.vary.vary_on_headers\" title=\"django.views.decorators.vary.vary_on_headers\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.views.decorators.vary.vary_on_headers()</span></code></a>, comme ceci :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.vary</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">vary_on_headers</span>\n\n<span class=\"nd\">@vary_on_headers</span><span class=\"p\">(</span><span class=\"s1\">&#39;User-Agent&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Dans ce cas, un mécanisme de cache (tel que le propre intergiciel de cache de Django) mettra en cache des versions séparées de la page pour chaque type de client (« user-agent ») différent.</p>\n<p>L’avantage d’utiliser le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">vary_on_headers</span></code> plutôt que de définir manuellement l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code> (en écrivant quelque chose comme <code class=\"docutils literal notranslate\"><span class=\"pre\">response['Vary']</span> <span class=\"pre\">=</span> <span class=\"pre\">'user-agent'</span></code>) est que le décorateur <em>complète</em> l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code> (qui peut déjà exister) au lieu de le redéfinir complètement ce qui pourrait écraser un éventuel contenu d’en-tête existant.</p>\n<p>Il est possible de transmettre plusieurs en-têtes à <code class=\"docutils literal notranslate\"><span class=\"pre\">vary_on_headers()</span></code>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"nd\">@vary_on_headers</span><span class=\"p\">(</span><span class=\"s1\">&#39;User-Agent&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Cookie&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Cela indique aux caches amonts de différencier <em>les deux</em>, ce qui signifie qu’à chaque combinaison de type de client et de cookie correspondra une valeur de cache propre. Par exemple, une requête avec le type de client <code class=\"docutils literal notranslate\"><span class=\"pre\">Mozilla</span></code> et la valeur de cookie <code class=\"docutils literal notranslate\"><span class=\"pre\">foo=bar</span></code> sera considérée différente d’une requête avec le type de client <code class=\"docutils literal notranslate\"><span class=\"pre\">Mozilla</span></code> et la valeur de cookie <code class=\"docutils literal notranslate\"><span class=\"pre\">foo=ham</span></code>.</p>\n<p>Comme la variation selon les cookies est très courante, il existe un décorateur <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie\" title=\"django.views.decorators.vary.vary_on_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.views.decorators.vary.vary_on_cookie()</span></code></a>. Ces deux vues sont équivalentes :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"nd\">@vary_on_cookie</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n<span class=\"nd\">@vary_on_headers</span><span class=\"p\">(</span><span class=\"s1\">&#39;Cookie&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Les en-têtes transmis à <code class=\"docutils literal notranslate\"><span class=\"pre\">vary_on_headers</span></code> ne sont pas sensibles à la casse ; <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;User-Agent&quot;</span></code> est équivalent à <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;user-agent&quot;</span></code>.</p>\n<p>Vous pouvez aussi utiliser directement une fonction utilitaire <a class=\"reference internal\" href=\"/fr/1.10/ref/utils/#django.utils.cache.patch_vary_headers\" title=\"django.utils.cache.patch_vary_headers\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.utils.cache.patch_vary_headers()</span></code></a>. Celle-ci définit ou complète l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><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\">render</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">patch_vary_headers</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s1\">&#39;template_name&#39;</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n    <span class=\"n\">patch_vary_headers</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s1\">&#39;Cookie&#39;</span><span class=\"p\">])</span>\n    <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">patch_vary_headers</span></code> accepte une instance <a class=\"reference internal\" href=\"/fr/1.10/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> comme premier paramètre et une liste de noms d’en-têtes insensibles à la casse comme second paramètre.</p>\n<p>Pour plus de détails sur les en-têtes <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code>, consultez la <span class=\"target\" id=\"index-6\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7231.html#section-7.1.4\"><strong>spécification officielle de Vary</strong></a>.</p>\n</section>\n<section id=\"controlling-cache-using-other-headers\">\n<h2>Contrôle du cache : utilisation d’autres en-têtes<a class=\"heading-anchor\" href=\"#controlling-cache-using-other-headers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>D’autres problèmes de cache incluent la confidentialité des données et la problématique de l’emplacement de stockage des données en cas de caches en cascade.</p>\n<p>Un utilisateur est généralement confronté à deux sortes de caches : son propre cache de navigateur (cache privé) et le cache de son fournisseur d’accès (cache public). Un cache public est partagé par de nombreux utilisateurs et contrôlé de manière externe. Cela pose des problèmes avec les données sensibles ; vous ne souhaitez probablement pas que votre numéro de compte bancaire soit stocké dans un cache public. Les applications Web doivent donc pouvoir indiquer aux caches quelles sont les données privées et celles qui sont publiques.</p>\n<p>La solution est d’indiquer que le contenu d’une page en cache devrait être « privé ». Pour faire cela avec Django, utilisez le décorateur de vue <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">cache_control()</span></code></a>. Exemple :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache_control</span>\n\n<span class=\"nd\">@cache_control</span><span class=\"p\">(</span><span class=\"n\">private</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Ce décorateur se charge d’envoyer les en-têtes HTTP appropriés en arrière-plan.</p>\n<p>Signalons que les réglages de contrôle de cache « private » et « public » sont mutuellement exclusifs. Le décorateur s’assure que la directive « public » est enlevée si « private » doit être défini (et vice versa). Un exemple d’utilisation de ces deux directives pourrait être un site de blog qui propose à la fois des articles privés et publics. Les articles publics peuvent être mis en cache dans n’importe quel cache partagé. Le code suivant utilise <a class=\"reference internal\" href=\"/fr/1.10/ref/utils/#django.utils.cache.patch_cache_control\" title=\"django.utils.cache.patch_cache_control\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.utils.cache.patch_cache_control()</span></code></a>, la façon manuelle de modifier l’en-tête de contrôle de cache (elle est appelée en interne par le décorateur <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">cache_control()</span></code></a>) :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">patch_cache_control</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.vary</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">vary_on_cookie</span>\n\n<span class=\"nd\">@vary_on_cookie</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">list_blog_entries_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_anonymous</span><span class=\"p\">:</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">render_only_public_entries</span><span class=\"p\">()</span>\n        <span class=\"n\">patch_cache_control</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"n\">public</span><span class=\"o\">=</span><span class=\"kc\">True</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\">render_private_and_public_entries</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"p\">)</span>\n        <span class=\"n\">patch_cache_control</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"n\">private</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n<p>Il est aussi possible de contrôler les caches amonts par d’autres moyens (voir <span class=\"target\" id=\"index-7\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7234.html\"><strong>RFC 7234</strong></a> pour des détails sur le cache HTTP). Par exemple, même si vous n’exploitez pas l’infrastructure de cache du côté serveur Django, il est tout de même possible de demander aux clients de mettre en cache une vue pour un certain temps à l’aide de la directive <span class=\"target\" id=\"index-8\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7234.html#section-5.2.2.8\"><strong>max-age</strong></a>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache_control</span>\n\n<span class=\"nd\">@cache_control</span><span class=\"p\">(</span><span class=\"n\">max_age</span><span class=\"o\">=</span><span class=\"mi\">3600</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Si vous utilisez l’intergiciel de cache, celui-ci définit déjà l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">max-age</span></code> avec la valeur du réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHE_MIDDLEWARE_SECONDS</span></code></a>. Dans ce cas, la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">max_age</span></code> personnalisée par le décorateur <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">cache_control()</span></code></a> est prioritaire et les valeurs d’en-têtes seront fusionnées correctement.</p>\n<p>Toute directive de réponse <code class=\"docutils literal notranslate\"><span class=\"pre\">Cache-Control</span></code> valide est acceptée dans <code class=\"docutils literal notranslate\"><span class=\"pre\">cache_control()</span></code>. Voici quelques exemples supplémentaires :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">no_transform=True</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">must_revalidate=True</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">stale_while_revalidate=nombre_secondes</span></code></p></li>\n</ul>\n<p>La liste complète des directives connues se trouve dans le <a class=\"reference external\" href=\"http://www.iana.org/assignments/http-cache-directives/http-cache-directives.xhtml\">registre IANA</a> (notez que toutes ne s’appliquent pas aux réponses).</p>\n<p>Si vous souhaitez utiliser des en-têtes pour désactiver totalement le cache, <a class=\"reference internal\" href=\"/fr/1.10/topics/http/decorators/#django.views.decorators.cache.never_cache\" title=\"django.views.decorators.cache.never_cache\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">never_cache()</span></code></a> est un décorateur de vue qui ajoute les en-têtes nécessaires pour s’assurer que la réponse ne sera pas mise en cache par les navigateurs ou d’autres caches. Exemple :</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">never_cache</span>\n\n<span class=\"nd\">@never_cache</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">myview</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</section>\n<section id=\"order-of-middleware\">\n<h2>Ordre dans <code class=\"docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code><a class=\"heading-anchor\" href=\"#order-of-middleware\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si vous utilisez l’intergiciel de cache, il est important de placer chacun des deux éléments au bon endroit dans le réglage <a class=\"reference internal\" href=\"/fr/1.10/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>. Ceci parce que l’intergiciel de cache a besoin de savoir à partir de quels en-têtes le stockage de cache doit varier. L’intergiciel ajoute toujours quelque chose à l’en-tête de réponse <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code> autant qu’il le peut.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> s’exécute durant la phase de réponse, lorsque les intergiciels sont exécutés en ordre inverse, et qu’un élément en haut de liste s’exécute <em>en dernier</em> pendant la phase de réponse. Ainsi donc, vous devez prendre soin de placer <code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> <em>avant</em> tout autre intergiciel susceptible d’ajouter quelque chose à l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code>. Les modules d’intergiciel suivants sont concernés :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">SessionMiddleware</span></code> ajoute <code class=\"docutils literal notranslate\"><span class=\"pre\">Cookie</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">GZipMiddleware</span></code> ajoute <code class=\"docutils literal notranslate\"><span class=\"pre\">Accept-Encoding</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">LocaleMiddleware</span></code> ajoute <code class=\"docutils literal notranslate\"><span class=\"pre\">Accept-Language</span></code></p></li>\n</ul>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">FetchFromCacheMiddleware</span></code>, de son côté, s’exécute durant la phase de requête, lorsque les intergiciels sont exécutés de haut en bas, et qu’un élément en haut de liste s’exécute <em>en premier</em> pendant la phase de requête. L’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">FetchFromCacheMiddleware</span></code> doit également être exécuté après que tout autre intergiciel ne modifie l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary</span></code>, c’est pourquoi il doit figurer dans la liste <em>après</em> ceux qui effectuent une telle modification.</p>\n</section>","rootId":"django-s-cache-framework","toc":[{"title":"Mise en place du cache","anchor":"setting-up-the-cache","children":[{"title":"Memcached","anchor":"memcached","children":[]},{"title":"Cache en base de données","anchor":"database-caching","children":[{"title":"Création de la table du cache","anchor":"creating-the-cache-table","children":[]},{"title":"Bases de données multiples","anchor":"multiple-databases","children":[]}]},{"title":"Cache sur système de fichiers","anchor":"filesystem-caching","children":[]},{"title":"Cache en mémoire locale","anchor":"local-memory-caching","children":[]},{"title":"Pseudo-cache (pour le développement)","anchor":"dummy-caching-for-development","children":[]},{"title":"Utilisation d’un moteur de cache personnalisé","anchor":"using-a-custom-cache-backend","children":[]},{"title":"Paramètres de cache","anchor":"cache-arguments","children":[]}]},{"title":"Le cache « par site »","anchor":"the-per-site-cache","children":[]},{"title":"Le cache par vue","anchor":"the-per-view-cache","children":[{"title":"Utilisation du cache par vue dans la configuration d’URL","anchor":"specifying-per-view-cache-in-the-urlconf","children":[]}]},{"title":"Cache de gabarits partiels","anchor":"template-fragment-caching","children":[]},{"title":"L’API de cache de bas niveau","anchor":"the-low-level-cache-api","children":[{"title":"Accès au cache","anchor":"accessing-the-cache","children":[]},{"title":"Utilisation de base","anchor":"basic-usage","children":[]},{"title":"Préfixe de clés de cache","anchor":"cache-key-prefixing","children":[]},{"title":"Versions dans le cache","anchor":"cache-versioning","children":[]},{"title":"Transformation de clé de cache","anchor":"cache-key-transformation","children":[]},{"title":"Avertissements de clé de cache","anchor":"cache-key-warnings","children":[]}]},{"title":"Caches amonts","anchor":"downstream-caches","children":[]},{"title":"Utilisation des en-têtes Vary","anchor":"using-vary-headers","children":[]},{"title":"Contrôle du cache : utilisation d’autres en-têtes","anchor":"controlling-cache-using-other-headers","children":[]},{"title":"Ordre dans MIDDLEWARE","anchor":"order-of-middleware","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/1.10/topics/"}],"prev":{"docname":"topics/auth/customizing","title":"Personnalisation de l’authentification dans Django","url":"/fr/1.10/topics/auth/customizing/"},"next":{"docname":"topics/conditional-view-processing","title":"Traitement conditionnel de vue","url":"/fr/1.10/topics/conditional-view-processing/"},"formats":{"html":"/fr/1.10/topics/cache/","markdown":"/fr/1.10/topics/cache.md","json":"/fr/1.10/topics/cache.json"},"source":"https://github.com/django/django/blob/stable/1.10.x/docs/topics/cache.txt","official":"https://docs.djangoproject.com/fr/1.10/topics/cache/","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","fr","ja","id","pt-br","es","el","pl"]}