Django Caching

Caching in Django kann auf verschiedenen Ebenen (oder Teilen der Site) implementiert werden. Sie können die gesamte Site oder bestimmte Teile mit verschiedenen Granularitätsstufen zwischenspeichern (in absteigender Reihenfolge der Granularität aufgeführt):

Caching konfigurieren

in den settings.py kann der Cache mit diversen Werten konfiguriert werden. Hier konfigurieren wir einen Local-Memory-Cache für den Entwicklungsserver:

Der Local-Memory-Cache sollte nicht im Produktivbetrieb eingesetzt werden, da er nicht skalierbar ist, sondern nur für einen einzelnen Rechner gedacht ist.

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
}

views cachen

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):
    ...

oder in den URls

from django.views.decorators.cache import cache_page

urlpatterns = [
    path('foo/<int:code>/', cache_page(60 * 15)(my_view)),
]

Template Caching

Auch Teile des Templates können gecached werden:

{% load cache %}
{% cache 500 sidebar %}
    .. sidebar ..
{% endcache %}

500 Seunden auch in Abhängigkeit von Daten, zum Beispiel in Abhängigeit des Users:

{% load cache %}
{% cache 500 sidebar request.user.username %}
    .. sidebar for logged in user ..
{% endcache %}

Low Level Api

>> from django.core.cache import cache
>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
>> # Wait 30 seconds for 'my_key' to expire...
>>> cache.get('my_key')
None

>>> # wie gewöhnlich kann man bei Dicts auch mit Default-Werten arbeiten,
>>> # falls der Key nicht vorhanden ist.
>>> cache.get('my_key', 'defaultWert')

Manchmal kann es Sinn machen, mit Sentinel-Objekten zur arbeiten.

>>> sentinel = object()
>>> cache.get('my_key', sentinel) is sentinel
False
>>> # Wait 30 seconds for 'my_key' to expire...
>>> cache.get('my_key', sentinel) is sentinel
True

Zum Beispiel soll der Key Bank auf None gesetzt werden und 10 Sekunden im Cache bleiben. Würden wir einfach mit get(“bank”) arbeiten, wüssten wir nicht, ob der Value None ist oder der Key gar nicht im Cache vorhanden.

>>> # Cache setzen
>>> cache.set("bank", None, 10)
>>> # es wird None zurückgegeben (weil das der Value ist)
>>> cache.get("bank", sentinel) is sentinel
False
>>> is sentinel, es wird immer noch None
>>> cache.get("bank", sentinel)
False
>>>  # get liefert jetzt als default das sentinel Objekt
>>> # und ist daher nicht mehr im Cache gespeichert
>>> cache.get("bank", sentinel) is sentinel
True