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 Levels¶
ganze Webseite cachen: https://docs.djangoproject.com/en/3.2/topics/cache/#the-per-site-cache
Views cachen:https://docs.djangoproject.com/en/3.2/topics/cache/#the-per-view-cache
Template Teile cachen: https://docs.djangoproject.com/en/3.2/topics/cache/#template-fragment-caching
Low Level Cache Api: https://docs.djangoproject.com/en/3.2/topics/cache/#the-low-level-cache-api
Caching Backends¶
MemCached: https://docs.djangoproject.com/en/3.2/topics/cache/#memcached
Datenban: https://docs.djangoproject.com/en/3.2/topics/cache/#database-caching
Dateisystem: https://docs.djangoproject.com/en/3.2/topics/cache/#filesystem-caching
Local Memory: https://docs.djangoproject.com/en/3.2/topics/cache/#local-memory-caching
Dummy Cache: https://docs.djangoproject.com/en/3.2/topics/cache/#dummy-caching-for-development
Redis (ab Django 4.x): https://docs.djangoproject.com/en/4.0/topics/cache/#redis
Für den Produtivbetrieb mit hohem Useraufkommen sollte Redis oder Memcached genutzt werden, da beide auf viele Server skaliert werden können.
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