root/docs/trunk/cache.txt

Revision 298, 29.4 kB (checked in by david, 1 year ago)

dures à trouver celles-là...

Line 
1 ===============================
2 Le framework de cache de Django
3 ===============================
4
5 Un des aspects fondamental des sites web dynamiques est, évidemment,
6 qu'ils sont dynamiques. A chaque fois qu'un utilisateur demande l'affichage
7 d'une page, le serveur web effectue tout un ensemble de calculs -- allant
8 des requêtes en base de données, jusqu'au rendu des gabarits, en passant
9 par la logique métier -- afin de créer la page que vos visiteurs voient.
10 Ceci est plus coûteux, en terme de surcharge de traitement, qu'une simple
11 lecture de fichier sur le systÚme de fichiers de votre serveur.
12
13 Pour la plupart des applications web, cette surcharge n'est pas un problÚme.
14 La plupart des applications web ne sont pas le washingtonpost.com ou
15 slashdot.org; ce sont simplement des sites de petites et moyennes taille
16 avec un traffic de même ampleur. Mais pour les sites possédant un traffic
17 moyen important, il est essentiel de réduire la surcharge autant que
18 possible.
19
20 C'est à ce moment que le cache entre en jeu.
21
22 Mettre en cache un objet consiste à sauvegarder le résultat d'un calcul
23 coûteux, de maniÚre à ne pas effectuer le traitement la prochaine fois.
24 Voici un pseudocode détaillant comme cela fonctionne pour les pages web
25 gérées dynamiquement::
26
27     pour une URL donnée, essayer de trouver la page dans le cache
28     si la page est dans le cache:
29         retourner la page cachée
30     sinon:
31         générer la page
32         sauvegarder la page générée dans le cache (pour la prochaine fois)
33         retourner la page générée
34
35 Django fourni un systÚme de cache robuste qui vous permet de sauvegarder
36 des pages dynamiques afin de ne pas avoir à recalculer chaque requête.
37 Par commodité, Django offre une granularité de cache sur plusieurs niveaux :
38 vous pouvez mettre en cache le résultat de sortie de vues spécifiques,
39 vous pouvez ne mettre en cache que les parties difficiles à restituer,
40 ou encore, vous pouvez mettre en cache votre site dans son entier.
41
42 Django fonctionne aussi trÚs bien avec les caches situés en amont, tels
43 que `Squid`_ et le cache des navigateurs. C'est le genre de cache que
44 vous ne contrÎlez pas, mais sur lequel vous pouvez agir (via les entêtes
45 HTTP) en indiquant quelles parties de votre site doivent être mises en
46 cache, et comment.
47
48 .. _Squid: http://www.squid-cache.org/
49
50 Configuration du cache
51 =======================
52
53 Le systÚme de cache ne nécessite qu'une petite partie de configuration.
54 A savoir, vous n'avez besoin que de lui dire où les données seront stockées
55 -- s'il s'agit de la base de données, du systÚme de fichiers, ou directement
56 en mémoire. C'est une décision importante car elle affecte les performances
57 de votre cache; oui, certains types de cache sont plus rapide que d'autres.
58
59 Votre choix de cache est stocké dans le paramÚtre de configuration
60 ``CACHE_BACKEND`` de votre fichier de configuration. Ce qui suit détaille
61 les différents valeurs permises pour CACHE_BACKEND.
62
63 Memcached
64 ---------
65
66 De loin le plus rapide et le plus efficace des systÚmes de cache disponibles
67 pour Django, Memcached est un framework de cache entiÚrement basé sur la
68 mémoire, initialement développé pour gérer les forts taux de charge du
69 LiveJournal.com et par la suite versé dans le libre par Danga Interactive.
70 Il est utilisé par des sites tels que Slashdot et Wikipedia pour réduire
71 les accÚs en base de données et améliorer les performances de maniÚre
72 significative.
73
74 Memcached est disponible gratuitement sur http://danga.com/memcached/ .
75 Il s'exécute en tant que démon et il lui est alloué une certaine quantité
76 de RAM. Tout ce qu'il fait est de fournir une interface -- une interface
77 *super-rapide* -- pour ajouter, récupérer et supprimer des données
78 arbitraires en cache. Toutes les données étant directement stockées en
79 mémoire, il n'y a donc pas de surcharge d'utilisation de la base de
80 données ou du systÚme de fichiers.
81
82 AprÚs avoir installé Memcached, vous devrez installer la couche de liaison
83 Python pour Memcached. Deux versions sont disponibles. Choisissez et
84 installez *un* des modules suivants :
85
86     * L'option la plus rapide est un module nommé ``cmemcache``, disponible
87       sur http://gijsbert.org/cmemcache/ . (Ce module est uniquement
88       compatible avec la version de développement de Django. Django 0.96
89       est uniquement compatible avec la seconde option qui suit.)
90      
91     * Si vous ne pouvez pas installer ``cmemcache``, vous pouvez installer
92       ``python-memcached``, disponible sur ftp://ftp.tummy.com/pub/python-memcached/ .
93       Si cette URL est brisée allez simplement sur le site de Memcached
94       (http://www.danga.com/memcached/) et récupérez la couche de liaison
95       Python depuis la section "Client APIs".
96      
97 Pour utiliser Memcached avec Django, affectez la valeur ``memcached://ip:port/``
98 à ``CACHE_BACKEND``, dans laquelle ``ip`` désigne l'adresse IP de votre
99 démon Memcached et ``port`` est le port sur lequel Memcached s'exécute.
100
101 Dans cet exemple, Memcached s'exécute en local (127.0.0.1) sur le port 11211::
102
103     CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
104
105 Une des fonctionnalités phares de Memcached est sa capacité partager
106 le cache à travers plusieurs serveurs. Pour utiliser cette fonctionnalité
107 ajoutez toutes les adresses de vos serveurs dans ``CACHE_BACKEND``, séparées
108 par un point virgule. Dans l'exemple qui suit, le cache est partagé à
109 travers les instances Memcached s'exécutant aux adresses IP 172.19.26.240
110 et 172.19.26.242, toutes deux sur le port 11211::
111
112     CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
113
114 Le cache basé sur la mémoire possÚde un inconvénient: du fait que les données
115 sont gardées en mémoire, les données seront perdues si votre serveur tombe
116 en panne. Clairement, la mémoire n'est pas destinée à la persistance de
117 données. Ne dédiez donc pas uniquement votre gestion de cache sur la mémoire.
118 En fait, aucun des systÚmes de cache de Django ne doit être utilisé comme
119 moyen de stockage permanent des données -- ils sont tous destinés à fournir
120 des solutions de cache, et non de stockage -- mais nous appuyons sur ce
121 point du fait que le cache basé sur la mémoire est particuliÚrement
122 temporaire.
123
124 Cache via la base de données
125 ----------------------------
126
127 Pour utiliser une table de données comme systÚme de cache, premiÚrement,
128 créez une table de cache dans votre base de données en exécutant la commande:
129
130     python manage.py createcachetable [nom_table_de_cache]
131
132 ...dans laquelle ``[nom_table_de_cache]`` est le nom de la table à créer.
133 (Ce nom peut être celui que vous voulez, tant qu'il s'agit d'un nom de
134 table valide qui n'est pas déjà utilisé dans votre base de données.) Cette
135 commande crée une unique table dans votre base de données dans le format
136 propre utilisé par le systÚme de cache de Django.
137
138 Une fois que vous avez créé cette table, affectez la valeur ``"db://nom_table"``
139 à ``CACHE_BACKEND``, où ``nom_table`` correspond au nom de votre table.
140 Dans cet exemple, le nom de la table de cache est ``ma_table_de_cache``::
141
142     CACHE_BACKEND = 'db://ma_table_de_cache'
143
144 Le cache en base de données fonctionne de maniÚre optimum lorsque vous
145 possédez un serveur de base de données rapide et bien indéxée.
146
147 Cache via le systÚme de fichiers
148 --------------------------------
149
150 Pour sauvegarder les éléments du cache sur un systÚme de fichiers, utilisez
151 le type de cache ``"file://"`` pour ``CACHE_BACKEND``. Par exemple, pour
152 stocker les données en cache dans ``/var/tmp/cache_django``, utilisez
153 cette configuration::
154
155     CACHE_BACKEND = 'file:///var/tmp/cache_django'
156
157 Vous noterez qu'il y a trois barres obliques successives vers le début de
158 cet exemple. Les deux premiÚres concernent ``file://``, et la troisiÚme est
159 la premiÚre lettre du chemin de répertoire, ``/var/tmp/cache_django``.
160
161 Le chemin de répertoire doit être de type absolu -- c'est-à-dire qu'il
162 doit commencer à partir de l'élément racine de votre systÚme de fichiers.
163 La barre oblique finale n'est pas obligatoire et ne revêt aucune
164 importance particuliÚre.
165
166 Assurez vous que le répertoire cible de la configuration existe bien et
167 qu'il est accessible en lecture et écriture par l'utilisateur systÚme
168 exécutant votre serveur web. Pour poursuivre l'exemple précédent, si votre
169 serveur est exécuté par l'utilisateur ``apache``, assurez vous que le
170 répertoire ``/var/tmp/cache_django`` existe et qu'il est accessible en
171 lecture et écriture par l'utilisateur ``apache``.
172
173 Cache via mémoire locale
174 ------------------------
175
176 Si vous voulez bénéficier des avantages de rapidité du cache en mémoire
177 mais que vous ne pouvez pas exécuter Memcached, regardez du cÎté du systÚme
178 de cache de mémoire locale. Ce cache est multi-processus et thread-safe
179 (exécution des processus parallÚles sécurisée). Pour l'utiliser, affecter
180 la valeur ``"locmem:///"`` à ``CACHE_BACKEND``. Par exemple::
181
182     CACHE_BACKEND = 'locmem:///'
183
184 Cache basique (expérimental)
185 ----------------------------
186
187 Un mono-processus basique de cache mémoire disponible via ``"simple:///"``.
188 Il sauvegarde simplement les données en cache du processus en cours,
189 impliquant qu'il ne peut être utilisé que dans des environnements de
190 développement ou de test. Par exemple ::
191
192     CACHE_BACKEND = 'simple:///'
193    
194 **Nouveau dans la version de développement de Django:** Ce systÚme de cache est
195 déprécié et sera supprimé dans une prochaine version. L'utilisation du systÚme
196 de cache ``locmem`` est maintenant recommandé.
197
198 Cache factice (expérimental)
199 ----------------------------
200
201 Enfin, Django s'accompagne d'un cache factice qui n'effectue aucun travail
202 de cache -- il implémente simplement l'interface de cache sans rien faire
203 d'autre.
204
205 Ceci est utile si vous avez un site en production qui a de fort besoin en
206 cache à plusieurs endroits différents mais un environnement de développement
207 et/ou de test qui ne nécessite pas de cache. Ainsi, votre environnement de
208 développement n'utilisera plus de cache, mais sans affecter celui de votre
209 environnement de production. Pour activer le cache factice, assignez
210 ``CACHE_BACKEND`` comme suit::
211
212     CACHE_BACKEND = 'dummy:///'
213
214 Arguments de CACHE_BACKEND
215 --------------------------
216
217 Tous les caches peuvent recevoir des arguments. Ils sont passés sous forme
218 de query-string au paramÚtre de configuration ``CACHE_BACKEND``. Les arguments
219 possibles sont les suivants :
220
221     timeout
222         Temps d'expiration par défaut, en secondes, à utiliser par le cache.
223         Défini par défaut à 5 minutes (300 secondes).
224
225     max_entries
226         Pour les caches bassique et via la base de données, le nombre maximum
227         d'entrées permises en cache avant effacement. Par défaut à 300.
228
229     cull_percentage
230         Pourcentage d'entrées éliminées quand max_entries est atteint. Le
231         véritable pourcentage est de 1/cull_percentage. De ce fait,
232         l'affectation cull_percentage=3 entraînera la suppression d'1/3
233         des entrées lorsque max_entries est atteint.
234        
235         Une valeur égale à 0 pour cull_percentage signifie la destruction
236         totale du cache lorsque max_entries est atteint. Ceci rend
237         l'élimination beaucoup plus rapide aux dépens de plus d'absence
238         dans l'antémémoire.
239
240 Dans cet exemple, ``timeout`` à pour valeur ``60``::
241
242     CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=60"
243
244 Dans cet exemple, ``timeout`` vaut ``30`` et ``max_entries`` est à ``400``::
245
246     CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=30&max_entries=400"
247
248 Les arguments non valides sont ignorés silencieusement, tout comme les
249 valeurs qui leurs sont associées.
250
251 Le cache par site
252 =================
253
254 Une fois le cache configuré la maniÚre la plus simple de l'utiliser est
255 encore de mettre en cache votre site dans son entier. Pour ce faire,
256 ajoutez ``'django.middleware.cache.CacheMiddleware'`` à votre paramÚtre
257 de configuration ``MIDDLEWARE_CLASSES``, comme dans l'exemple qui suit::
258
259     MIDDLEWARE_CLASSES = (
260         'django.middleware.cache.CacheMiddleware',
261         'django.middleware.common.CommonMiddleware',
262     )
263
264 (L'ordre des ``MIDDLEWARE_CLASSES`` importe. Voir
265 `Ordre des MIDDLEWARE_CLASSES`_ ci-dessous)
266
267 Puis, ajoutez les paramÚtres de configuration obligatoires suivants dans
268 votre fichier de configuration de Django:
269
270 * ``CACHE_MIDDLEWARE_SECONDS`` -- Le nombre de secondes pendant lesquelles
271   chaque page doit être cachée.
272 * ``CACHE_MIDDLEWARE_KEY_PREFIX`` -- Si le cache est partagé à travers
273   plusieurs sites utilisant la même installation de Django, affectez lui
274   le nom du site, ou une autre chaîne de caractÚres unique pour cette
275   instance de Django, afin de prévenir les interblocages de clés. Laissez
276   vide si cela n'a pas d'importance pour vous.
277
278 Le middleware de cache met en cache toute page ne contenant pas de paramÚtre
279 passé via GET ou POST. De maniÚre optionnelle, si le paramÚtre
280 ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` contient la valeur ``True``, seules
281 les requêtes anonymes (i.e., celles qui ne sont pas exécutées par un
282 utilisateur authentifié seront cachées. C'est une maniÚre simple et
283 efficace de désactiver le cache pour les pages spécifiques aux utilisateurs
284 (incluant les pages de l'interface d'administration de Django). Notez que
285 si vous utilisez ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY``, vous devriez vous
286 assurez que vous avez bien activé ``AuthenticationMiddleware`` et que
287 ``AuthenticationMiddleware`` soit placé avant ``CacheMiddleware`` dans
288 vos ``MIDDLEWARE_CLASSES``.
289
290 De plus, ``CacheMiddleware`` ajoute automatiquement quelques entrées dans
291 chaque ``HttpResponse``:
292
293 * Assigne à l'entête ``Last-Modified`` la date et l'heure courante quand
294   une nouvelle version (non caché) de la page est demandée.
295 * Assigne à l'entête ``Expires`` la date et l'heure courante augmentée du
296   nombre de secondes définies par ``CACHE_MIDDLEWARE_SECONDS``.
297 * Assigne à l'entête ``Cache-Control`` la durée de vie maximum de la page
298   -- de même, basée sur le paramÚtre de configuration ``CACHE_MIDDLEWARE_SECONDS``
299
300 Voir la `documentation sur les middlewares`_ pour en savoir plus sur les
301 middleware.
302
303 .. _`documentation sur les middlewares`: ../middleware/
304
305 **Nouveau dans la version de développement de Django**
306
307 Si une vue gÚre son propre temps d'expiration de cache (i.e. possÚde une section
308 ``max-age`` dans son entête ``CacheControl``) alors la page sera mise en cache
309 jusqu'à expiration du temps, au lieu de ``CACHE_MIDDLEWARE_SECONDS``.
310 L'utilisation des décorateurs de ``django.views.decorators.cache`` facilite
311 l'assignation du temps d'expiration pour une vue (via le décorateur
312 ``cache_control``) ou la désactivation du cache pour une vue (via le décorateur
313 ``never_cache``). Voir la section `Utilisation d'autres entêtes`__ pour plus de
314 décorateurs.
315
316 __ `ContrÎle du cache: Utilisation d'autres entêtes`_
317
318 Le cache par vue
319 ================
320
321 Une maniÚre plus granulaire d'utiliser le framework de cache est de mettre
322 en cache le résultat de sortie de chaque vue. Le ``django.views.decorators.cache``
323 défini un décorateur ``cache_page`` qui mettra automatiquement en cache
324 la réponse de la vue pour vous. C'est trÚs facile à utiliser::
325
326     from django.views.decorators.cache import cache_page
327
328     def slashdot_cela(request):
329         ...
330
331     slashdot_cela = cache_page(slashdot_cela, 60 * 15)
332
333 Ou, en utilisant la syntaxe des décorateurs de Python 2.4::
334
335     @cache_page(60 * 15)
336     def slashdot_cela(request):
337         ...
338
339 ``cache_page`` ne prends qu'un seul argument : le temps d'expiration du
340 cache, en secondes. Dans l'exemple ci-dessus, le résultat de la vue
341 ``slashdot_cela()`` sera mis en cache pendant 15 minutes.
342
343 Cache des gabarits par fragments
344 ================================
345
346 **Nouveau dans la version de développement de Django**
347
348 Si vous avez besoin de plus de contrÃŽle, vous pouvez aussi mettre en cache des
349 fragments de gabarits en utilisant le tag de gabarit ``cache``. Pour que votre
350 gabarit puisse accéder à ce tag, ajoutez ``{% load cache %}`` vers le début de
351 votre gabarit.
352
353 Le tag de gabarit ``{% cache %}`` met en cache le contenu du bloc pour la
354 période de temps donnée. Il prend au moins deux arguments : le temps maximum de
355 mise en cache, en secondes, et le nom du fragment de cache. Par exemple::
356
357     {% load cache %}
358     {% cache 500 barre_laterale %}
359         .. barre_laterale ..
360     {% endcache %}
361
362 Certaines fois, vous aurez besoin de mettre en cache plusieurs copies d'un
363 fragment dépendant de données dynamiques apparaissant au sein même du fragment.
364 Par exemple, vous voudriez une copie séparée de la barre latérale utilisée dans
365 l'exemple précédent pour chaque utilisateur de votre site. Pour ce faire,
366 passez un argument supplémentaire au tag de gabarit ``{% cache %}`` pour
367 identifier le fragment de maniÚre unique::
368
369     {% load cache %}
370     {% cache 500 barre_laterale request.user.username %}
371         .. barre_laterale pour l'utilisateur connecté ..
372     {% endcache %}
373
374 Il est tout a fait possible de spécifier plus d'un argument pour identifier le
375 fragment. Passez autant d'arguments à ``{% cache %}`` que nécessaire.
376
377 L'API de cache de bas niveau
378 ============================
379
380 Des fois, cependant, mettre en cache l'intégralité d'une page ne vous
381 intéresse pas forcément. Par exemple, vous pouviez trouver qu'il n'est
382 nécessaire que de mettre en cache le résultat d'une requête en base
383 de données coûteuse. Dans ce genre de cas, vous pouvez utiliser l'API de
384 cache de bas niveau pour mettre en cache des objets avec le niveau de
385 granularité de votre choix.
386
387 L'API de cache est simple. Le module de cache, ``django.core.cache``, met
388 à disposition un objet ``cache`` automatiquement créé selon le paramÚtre
389 de configuration ``CACHE_BACKEND``::
390
391     >>> from django.core.cache import cache
392
393 L'interface de base est ``set(clé, valeur, temps_expiration_en_secondes)``
394 et ``get(clé)``::
395
396     >>> cache.set('ma_clé, 'bonjour, monde!', 30)
397     >>> cache.get('my_clé)
398     'bonjour, monde!'
399
400 L'argument ``temps_expiration_en_secondes`` est optionnel et est par défaut
401 égal à la valeur définie dans le paramÚtre de configuration ``CACHE_BACKEND``
402 (expliqué plus haut).
403
404 Si l'objet n'existe pas en cache, ``cache.get()`` retourne ``None``::
405
406     >>> cache.get('une_autre_clé')
407     None
408
409     # Attendre 30 secondes que 'ma_clé' expire...
410
411     >>> cache.get('ma_clé)
412     None
413
414 get() peut prendre un argument ``default``::
415
416     >>> cache.get('ma_clé', 'est expiré')
417     'est expiré'
418
419 **Nouveau dans la version de développement de Django** Pour ajouter une clé
420 uniquement si elle n'existe pas déjà, utilisez la méthode ``add()``. Elle prend
421 les mêmes paramÚtres que ``set()``, sauf qu'elle n'essayera pas de mettre à jour
422 le cache si la clé spécifiée est déjà présente::
423
424     >>> cache.set('ajout_clé', 'Valeur initiale')
425     >>> cache.add('ajout_clé', 'Nouvelle valeur')
426     >>> cache.get('ajout_clé')
427     'Valeur initiale'
428
429 Il y aussi une méthode get_many() qui n'attaque le cache qu'une seule fois.
430 get_many() retourne un dictionnaire avec toutes les clés que vous avez
431 demandé pour celles qui existent encore en cache (et n'ont pas expiré):
432
433     >>> cache.set('a', 1)
434     >>> cache.set('b', 2)
435     >>> cache.set('c', 3)
436     >>> cache.get_many(['a', 'b', 'c'])
437     {'a': 1, 'b': 2, 'c': 3}
438
439 Finalement, vous pouvez directement supprimer des clés avec ``delete()``.
440 C'est une maniÚre facile de supprimer un objet particulier du cache::
441
442     >>> cache.delete('a')
443
444 C'est tout. Le cache possÚde quelques restrictions : Vous pouvez mettre
445 en cache tout objet qui se conserve de maniÚre sécurisée tandis que les
446 clés doivent être des chaînes de caractÚres.
447
448 Les caches en amont
449 ===================
450
451 Jusqu'ici, ce document s'en est tenu à la mise en cache de *vos* données.
452 Mais un autre type de cache est aussi pertinent pour le développement web:
453 le cache géré par les serveurs de cache en "amont". Ce sont des systÚmes
454 qui mettent en cache les pages pour les utilisateurs avant même que la
455 requête n'atteigne votre site web.
456
457 Voici quelques exemples de caches en amont:
458
459     * Votre FAI peut mettre en cache certaines pages. Ainsi, si vous
460       requêtez le page de undomaine.com, votre FAI vous enverra la page
461       sans accéder directement à undomaine.com.
462      
463     * Votre site Django est derriÚre un proxy web `Squid`_ qui met en cache
464       les pages pour améliorer les performances. Dans ce genre de cas,
465       chaque requête est d'abord gérée ar Squid, et ne la repassera à
466       votre application que si besoin est.
467      
468     * Votre navigateur web met aussi en cache les pages. Si une page web
469       envoi les bons entêtes, votre navigateur utilisera la copie locale
470       (en cache) pour les requêtes suivantes, sur cette page.
471
472 Le cache exercé en amont amÚne un bon boost de performance, mais il y a
473 un danger à son utilisation: Le contenu des pages web diffÚrent en regard
474 de l'authentification, de l'hÎte ou d'autres variables, et les systÚmes
475 de cache qui sauvegarde les pages en aveugle en se basant seulement sur
476 l'URL peuvent exposer des données incorrectes ou sensibles aux utilisateurs
477 qui suivent et demandent ces même pages.
478
479 Par exemple, disons que vous faîtes fonctionner une application web de
480 gestion de courriels, et que le contenu de la page "boîte de réception"
481 dépend de l'utilisateur qui est connecté. Si un FAI met aveuglément en
482 cache votre site, alors le premier utilisateur qui se connectera via cet
483 FAI verra apparaître sa page contenant ses données personnelles sur celle
484 des utilisateurs qui suivent. Ce qui n'est pas top.
485
486 Heureusement, HTTP apporte une solution à ce problÚme: Un ensemble d'entêtes
487 HTTP existe pour instruire les mécanismes de cache et différencier le
488 contenu de cache en fonction de variables données, et d'ordonner aux
489 mécanismes de cache de ne pas mettre en cache certaines pages.
490
491 .. _`Squid`: http://www.squid-cache.org/
492
493 Utilisation des entêtes Vary
494 ============================
495
496 Un de ces entêtes est Vary. Il défini quelles sont les entêtes de la
497 requête que le mécanisme de cache doit prendre en compte lors de la
498 construction de sa clé de cache. Par exemple, si le contenu d'une page
499 web dépend de la langue préférée de l'utilisateur, la page est dite à
500 "varier en fonction de la langue".
501
502 Par défaut, le systÚme de cache de Django crée sa clé de cache en utilisant
503 le chemin requêté -- e.g., ``"/nouvelles/2005/juin/23/vol_de_banque/"``.
504 Ceci veut dire que chaque requête sur cette URL utilisera la même version
505 en cache, sans se soucier des différences émanant des agents utilisateurs
506 tels que les cookies ou la langue.
507
508 C'est à ce moment que ``Vary`` entre en jeu.
509
510 Si votre page Django génÚre un contenu différent en fonction des entêtes
511 des requêtes -- tels les cookies, la langue ou l'agent utilisateur -- vous
512 aurez besoin de l'entête ``Vary`` pour spécifier au mécanisme de cache
513 que le contenu de votre page dépend de ce genre de chose.
514
515 Pour faire cela avec Django, utilisez le décorateur de vue taillé sur
516 mesure ``vary_on_headers``, de cette maniÚre::
517
518     from django.views.decorators.vary import vary_on_headers
519
520     # Syntaxe Python 2.3.
521     def ma_vue(request):
522         ...
523     ma_vue = vary_on_headers(ma_vue, 'User-Agent')
524
525     # Syntaxe décorateur de Python 2.4.
526     @vary_on_headers('User-Agent')
527     def ma_vue(request):
528         ...
529
530 Ici, un mécanisme de cache (tel que le middleware de cache propre à Django)
531 mettra en cache une version séparée de la page pour chaque agent utilisateur
532 unique.
533
534 L'avantage d'utiliser le décorateur ``vary_on_headers`` au lieu d'effectuer
535 manuellement le paramétrage de l'entête ``Vary`` (en utilisant quelque
536 chose comme ``response['Vary'] = 'user-agent'``) est que le décorateur
537 ajoute la donnée d'entête ``Vary`` (qui existe peut être déjà) au lieu
538 de simplement la redéfinir.
539
540 Vous pouvez ajouter plusieurs entêtes à ``vary_on_headers()``::
541
542     @vary_on_headers('User-Agent', 'Cookie')
543     def ma_vue(request):
544         ...
545
546 Du fait que la dépendance via un cookie est un cas commun, il existe un
547 décorateur ``vary_on_cookie``. Ces deux vues sont équivalentes::
548
549     @vary_on_cookie
550     def ma_vue(request):
551         ...
552
553     @vary_on_headers('Cookie')
554     def ma_vue(request):
555         ...
556
557 Vous noterez aussi que les entêtes que vous passez à ``vary_on_headers``
558 ne sont pas sensibles à la casse. ``"User-Agent"`` est identique à ``"user-agent"``.
559
560 Vous pouvez aussi directement utiliser l'assistant ``django.utils.cache.patch_vary_headers``::
561
562     from django.utils.cache import patch_vary_headers
563     def ma_vue(request):
564         ...
565         reponse = render_to_response('nom_gabarit', context)
566         patch_vary_headers(reponse, ['Cookie'])
567         return reponse
568
569 ``patch_vary_headers`` prends une instance ``HttpResponse`` en tant que
570 premier argument et une liste ou un tuple de noms d'entêtes en second
571 argument.
572
573 Pour en savoir plus sur les headers Vary, regardez la `spécification
574 officielle de vary`_.
575
576 .. _`spécification officielle de vary`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44
577
578 ContrÎle du cache: Utilisation d'autres entêtes
579 ===============================================
580
581 Un autre problÚme avec le cache est la protection de vos données et la
582 question de savoir où vos données doivent être stockées parmi la cascade
583 de systÚmes de cache.
584
585 Un utilisateur est généralement en proie à deux types de cache: son propre
586 cache de navigateur (un cache privé) et le cache de son fournisseur d'accÚs
587 (un cache public). Un cache public est utilisé par de multiple utilisateurs
588 et contrÎlé par d'autres. Ceci pose problÚme pour les données sensibles:
589 Vous ne voulez pas, par exemple, que votre compte bancaire soit stocké
590 dans un cache public.
591
592 La solution est d'indiquer que la page en cache doit être "privée". Pour
593 faire cela dans Django, utilisez le décorateur de vue ``cache_control``.
594 Exemple::
595
596     from django.views.decorators.cache import cache_control
597     @cache_control(private=True)
598     def ma_vue(request):
599         ...
600
601 Ce décorateur prendra soin d'envoyer l'entête HTTP appropriée de maniÚre
602 transparente.
603
604 Il y a d'autres maniÚres de contrÎler les paramÚtres de cache. Par exemple,
605 HTTP permet aux applications de faire ce qui suit:
606
607     * Définir le temps maximum pendant lequel une page est en cache.
608     * Déterminer si le cache doit systématiquement vérifier qu'une nouvelle
609       version existe, ne délivrant le contenu en cache seulement s'il
610       n'y a pas eu de changements. (Certains systÚmes de cache peuvent
611       délivrer du contenu en cache même si la page cÃŽté serveur a changé
612       -- tout simplement parce qu'une copie existe en cache et qu'elle
613       n'est pas expirée.)
614
615 Dans Django, utilisez le décorateur de vue ``cache_control`` pour spécifier
616 ce genre de paramÚtres de cache. Dans l'exemple qui suit, ``cache_control``
617 indique aux systÚmes de caches de revalider leur cache à chaque accés et
618 de ne garder en cache les éléments que pendant, au plus, 3600 secondes::
619
620     from django.views.decorators.cache import cache_control
621     @cache_control(must_revalidate=True, max_age=3600)
622     def ma_vue(request):
623         ...
624
625 Toutes les directives ``Cache-Control`` valides pour HTTP le sont aussi
626 pour ``cache_control()``. Voici la liste complÚte:
627
628     * ``public=True``
629     * ``private=True``
630     * ``no_cache=True``
631     * ``no_transform=True``
632     * ``must_revalidate=True``
633     * ``proxy_revalidate=True``
634     * ``max_age=nombre_secondes``
635     * ``s_maxage=nombre_secondes``
636
637 Pour des plus amples détails sur les directives Cache-Control de HTTP,
638 regardez la `spécification de Cache-Control`_.
639
640 (Notez que le middleware de cache assigne déjà le max-age de l'entête via
641 la valeur du paramÚtre de configuration ``CACHE_MIDDLEWARE_SETTINGS``. Si
642 vous utilisez une autre valeur de ``max_age`` dans le décorateur
643 ``cache_control``, ce dernier obtiendra la précédente, et la valeur de
644 l'entité sera correctement assignée.)
645
646 Si vous désirez utiliser les entêtes pour désactiver le cache dans son entier,
647 le décorateur de vue ``django.views.decorators.cache.never_cache`` ajoute des entêtes
648 pour s'assurer que la réponse ne sera pas mise en cache par les navigateurs ou
649 d'autres systÚmes de caches. Exemple::
650
651     from django.views.decorators.cache import never_cache
652     @never_cache
653     def ma_vue(request):
654         ...
655
656 .. _`spécification de Cache-Control`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
657
658 Autres optimisations
659 ====================
660
661 Django est fourni avec plusieurs autres middlewares qui peuvent vous aider
662 à optimiser les performances de vos applications:
663
664     * ``django.middleware.http.ConditionalGetMiddleware`` ajoute le support
665       des GET conditionnels. Ceci utilise les entêtes ``ETag`` et ``Last-Modified``.
666
667     * ``django.middleware.gzip.GZipMiddleware`` compresse le contenu pour
668       les navigateurs acceptant la compression gzip (tous les navigateurs
669       modernes).
670
671 Ordre des MIDDLEWARE_CLASSES
672 ============================
673
674 Si vous utilisez ``CacheMiddleware``, il est important de le disposer à
675 la bonne place dans le paramÚtre de configuration ``MIDDLEWARE_CLASSES``,
676 du fait que le middleware de cache à besoin de connaître sur quels entêtes
677 le contenu du cache varie. Le middleware ajoute systématiquement quelque
678 chose à l'entête ``Vary`` de la réponse dÚs qu'il le peut.
679
680 Ajoutez le ``CacheMiddleware`` *avant* tout middleware pouvant ajouter
681 quelque chose à l'entête ``Vary`` (les middlewares réponse sont appliqués en
682 sens inverse). Les middlewares suivants sont concernés:
683
684     * ``SessionMiddleware`` ajoute ``Cookie``
685     * ``GZipMiddleware`` ajoute ``Accept-Encoding``
686     * ``LocaleMiddleware`` ajoute ``Accept-Language``
687
Note: See TracBrowser for help on using the browser.