Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Funktionieren des Dekorators @cache_page() im django-redis-cache

cache_page decorator ist ein Django-Decorator, kein Django-Redis-Decorator. Wenn Sie also einen Standard-Cache wie memcached in Django verwendet hätten, hätte der cache_page-Decorator die gleichen Schlüssel in memcached erstellt. Hier ist der Decorator-Basiscode entlang der Doc-Zeichenfolge:

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

"""Decorator für Aufrufe, der versucht, die Seite aus dem Cache zu holen und den Cache füllt, wenn sich die Seite noch nicht im Cache befindet. Der Cache wird durch die URL und einige Daten aus den Headern verschlüsselt. Zusätzlich gibt es das Schlüsselpräfix, das heißt Wird verwendet, um verschiedene Cache-Bereiche in einem Multi-Site-Setup zu unterscheiden. Sie könnten zum Beispiel die get_current_site().domain verwenden, da diese in einem Django-Projekt eindeutig ist. Außerdem werden alle Header aus dem Vary-Header der Antwort beim Caching berücksichtigt – nur wie die Middleware."""

Es werden also von Natur aus mehrere Schlüssel erstellt, einer für Header und der andere für den HTTPResponse-Inhalt. Es erstellt die Schlüssel basierend auf Header und Inhalt, sodass jede Änderung des Headers den Cache ungültig macht (z. B. bei unterschiedlichen Headern), d . Beispiele für verschiedene Anforderungsheader können das Senden von Anmeldeinformationen über dieselbe Seite für verschiedene angemeldete Benutzer oder das Bereitstellen unterschiedlicher Inhalte für dieselbe URL basierend auf den in den Headern vorhandenen Benutzeragenteninformationen für Mobilgeräte/Desktops sein. Hier ist der Cache-Schlüsselcode 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