Skip to content

Caching

Django’s cache framework

pseudocode explaining how this would work for a dynamically generated web page:

graph TD
    A[Given a URL] --> B{Page in cache?}
    B -->|Yes| C[Return cached page]
    B -->|No| D[Generate the page]
    D --> E[Save generated page in cache]
    E --> F[Return generated page]

Different level of cache granualarity in Django:

  • Cache output of specific views
  • Cache only the pieces that are difficult to produce
  • Cache entire site

Setting up the cache

https://docs.djangoproject.com/en/5.1/topics/cache/#setting-up-the-cache

https://docs.wagtail.org/en/latest/advanced_topics/performance.html#cache

https://github.com/jazzband/django-redis

Python
# Wagtail recommends using redis for caching
# https://docs.wagtail.org/en/stable/advanced_topics/performance.html#cache
# https://github.com/jazzband/django-redis
CACHES = {
    'default': env.cache(default={
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': env('CACHE_URL'),
        'OPTIONS': {
            'COMPRESSOR': "django_redis.compressors.zlib.ZlibCompressor",
            'COMPRESS_MIN_LEN': 1024,  # Compress only values larger than 1KB
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        }
    }),
}

Different caching methods in Django

Per-site cache

This caches entire site for all users. Best for static sites with content that rarely changes.

Per-view cache

This caches the output of individual views. More flexibility than per-site caching. Can be tailored to cache only the views that benefit most from caching.

Template Fragment caching ✅

This caches only parts of a template, rather than the entire page. Sites with complex pages where only parts of the page change frequently.

Template fragment caching

https://docs.wagtail.org/en/latest/topics/writing_templates.html#template-fragment-caching

Django supports template fragment caching, which allows caching portions of a template. Using Django’s {% cache %} tag natively with Wagtail can be dangerous as it can result in preview content being shown to end users. Instead, Wagtail provides 2 extra template tags which can be loaded from wagtail_cache:

Django/Jinja
{% load static wagtailcore_tags wagtail_cache i18n%}
{% get_current_language as LANGUAGE_CODE %}
{% wagtailcache 600 "header" page.cache_key  LANGUAGE_CODE %}
<header class="d-flex flex-wrap justify-content-between py-1">
    <img src="{% static 'img/logo.svg' %}" alt="" class="logo">
    {% include 'includes/logo.html' %}
    {# language switch #}
    {% if page %}
        <div class="d-flex z-2 mx-2">
        {% for translation in page.get_translations.live %}
            <a href="{% pageurl translation %}" class="nav-link align-self-center">
                <div class="btn btn-outline-dark mx-1">{{ translation.locale.language_code }}</div>
            </a>
        {% endfor %}
        </div>
    {% endif %}
</header>
{% endwagtailcache %}

{% wagtailcache 600 "header" page.cache_key LANGUAGE_CODE %} here the header is the key and it must changed!!.