Redis
 sql >> Database >  >> NoSQL >> Redis

Funzionamento del decoratore @cache_page() in django-redis-cache

cache_page decorator è un decoratore django, non un decoratore django-redis. Quindi, se stavi usando una cache predefinita come memcached in django, il decoratore cache_page avrebbe creato le stesse chiavi in ​​memcached. Ecco il codice base del decoratore lungo la stringa doc:

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

""" Decoratore per le viste che prova a recuperare la pagina dalla cache e popola la cache se la pagina non è ancora nella cache. La cache è codificata dall'URL e da alcuni dati dalle intestazioni. Inoltre c'è il prefisso della chiave che è utilizzato per distinguere diverse aree della cache in una configurazione multisito. Puoi usare theget_current_site().domain, ad esempio, poiché è unico in un Djangoproject.Inoltre, tutte le intestazioni dell'intestazione Vary della risposta verranno prese in considerazione durante la memorizzazione nella cache, solo come fa il middleware."""

Quindi, intrinsecamente sta creando più chiavi, una per le intestazioni e l'altra per il contenuto HTTPResponse. Crea le chiavi in ​​base all'intestazione e al contenuto, in modo che qualsiasi modifica nell'intestazione invalidi la cache (ad esempio in caso di intestazioni variabili), cioè anche con gli stessi parametri nell'url, ma contenuto diverso nelle intestazioni delle richieste avrai cache separate . Esempi di intestazioni di richieste diverse possono essere l'invio di informazioni di accesso sulla stessa pagina per diversi utenti che hanno effettuato l'accesso o la pubblicazione di contenuti diversi per lo stesso URL in base alle informazioni sull'agente utente mobile/desktop presenti nelle intestazioni. Ecco il codice della chiave della cache in 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