Redis
 sql >> Base de données >  >> NoSQL >> Redis

Fonctionnement du décorateur @cache_page() dans django-redis-cache

cache_page decorator est un décorateur django, pas un décorateur django-redis. Donc, si vous utilisiez un cache par défaut comme memcached dans django, le décorateur cache_page aurait créé les mêmes clés dans memcached. Voici le code de base du décorateur le long de la chaîne doc :

https://github.com/django/django/blob/711123e1cdaf3b08c876c045d8d38decdc7a63d3/django/views/decorators/cache.py#L8

""" Décorateur pour les vues qui essaient d'obtenir la page du cache et remplissent le cache si la page n'est pas encore dans le cache. Le cache est codé par l'URL et certaines données des en-têtes. De plus, il y a le préfixe de clé qui est utilisé pour distinguer différentes zones de cache dans une configuration multi-site. Vous pouvez utiliser le get_current_site().domain, par exemple, car il est unique dans un projet Django. De plus, tous les en-têtes de l'en-tête Vary de la réponse seront pris en compte lors de la mise en cache -- comme le fait le middleware."""

Ainsi, il crée intrinsèquement plusieurs clés, une pour les en-têtes et une autre pour le contenu HTTPResponse. Il crée les clés en fonction de l'en-tête et du contenu, de sorte que tout changement d'en-tête invalide le cache (par exemple en cas d'en-têtes variables), c'est-à-dire même avec les mêmes paramètres dans l'url, mais un contenu différent dans les en-têtes de requête, vous aurez des caches séparés . Des exemples de différents en-têtes de requête peuvent être l'envoi d'informations de connexion sur la même page pour différents utilisateurs connectés, ou la diffusion de contenus différents pour la même URL en fonction des informations de l'agent utilisateur mobile/de bureau présentes dans les en-têtes. Voici le code de la clé de cache dans Django :

def _generate_cache_key(request, method, headerlist, key_prefix):
    """Return a cache key from the headers given in the header list."""
    ctx = hashlib.md5()
    for header in headerlist:
        value = request.META.get(header)
        if value is not None:
            ctx.update(force_bytes(value))
    url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
    cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
        key_prefix, method, url.hexdigest(), ctx.hexdigest())
    return _i18n_cache_key_suffix(request, cache_key)


def _generate_cache_header_key(key_prefix, request):
    """Return a cache key for the header cache."""
    url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
    cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
        key_prefix, url.hexdigest())
    return _i18n_cache_key_suffix(request, cache_key)


def get_cache_key(request, key_prefix=None, method='GET', cache=None):
    """
    Return a cache key based on the request URL and query. It can be used
    in the request phase because it pulls the list of headers to take into
    account from the global URL registry and uses those to build a cache key
    to check against.
    If there isn't a headerlist stored, return None, indicating that the page
    needs to be rebuilt.
    """
    if key_prefix is None:
        key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
    cache_key = _generate_cache_header_key(key_prefix, request)
    if cache is None:
        cache = caches[settings.CACHE_MIDDLEWARE_ALIAS]
    headerlist = cache.get(cache_key)
    if headerlist is not None:
        return _generate_cache_key(request, method, headerlist, key_prefix)
    else:
        return None