Learn Wagtail Course

How to Add Template Caching

It's easy to get distracted inside a template and forget about the cost of looking up data in a database. That's actually a benefit to using a framework like Django and a CMS like Wagtail: you don't have to worry about very much.

But as your website grows, the number of queries and amount of processing power your website needs will increase, and that will slow down your page load time. Django and Wagtail are already very conscious of this and work towards doing their best to keep your site fast and efficient. It's also easy to take advantage of the features we're given and make a terribly slow website. Admit it: we've all done it.

In this tutorial I'll show you how to enable template fragment caching, and in the video I'll teach you why caching is important and how it's beneficial, and how it can trick you into thinking there's a problem when it's really just cache being good at it's job.

There are many different types of caching. We're strictly looking at template fragment caching in this tutorial.

settings.py

Open your settings.py file. In this tutorial we used dev.py, but if you want caching to work in production simple paste this code into your production.py file.

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
        "LOCATION": "/path/to/your/site/cache"
    }
}

Note: the LOCATION key value pair needs to be changed in the above code. Point it towards a directory called "cache" in your project. If you're unsure how to get your project location, follow these steps:

  1. Open your terminal
  2. cd into your project
  3. type pwd

Template files

Next you'll need to identify heavy query areas of your website. Navigation/headers are usually good. StreamFields can be good too. Beautiful jumbotrons or hero areas with lots of custom content would be a good place to cache. Listing pages are good candidates for template fragment caching too.

On any template you want to use caching, make sure you load your cache tag. And then add a section you'd like to cache.

{% extends "base.html" %}
{% load wagtailimages_tags cache %}

{% block content %}
    {% for post in posts %}
        {% cache 604800 blog_post_preview post.id %}
            <div class="row mt-5 mb-5">
                <div class="col-sm-3">
                    {% image post.banner_image fill-250x250 as blog_img %}
                    <a href="{{ post.url }}">
                        <img src="{{ blog_img.url }}" alt="{{ blog_img.alt }}" style='width: 100%;'>
                    </a>
                </div>
                <div class="col-sm-9">
                    <a href="{{ post.url }}">
                        <h2>{{ post.custom_title }}</h2>
                        {% if post.specific.subtitle %}
                            <p>{{ post.specific.subtitle }}</p>
                        {% endif %}
                        <a href="{{ post.url }}" class="btn btn-primary mt-4">Read More</a>
                    </a>
                </div>
            </div>
        {% endcache %}
    {% endfor %}
{% endblock content %}

If you applied your caching correctly, this will cache loop cycle into its own .djcache file. This is useful for pagination. But you can cache outside of a for loop as well. For example, in the video I cached the entire navigation menu loop in base.html.

{% load cache %}

{% cache 604800 navigation %}
    {% for item in navigation.menu_items.all %}
        <li>
            <a href="{{ item.link }}" class="nav-link"{% if item.open_in_new_tab %} target="_blank"{% endif %}>{{ item.title }}</a>
        </li>
    {% endfor %}
{% endcache %}

Deleting Cache

You'll eventually need to delete your cache. In the video I demonstrated how caching gets in the way of updating your website's navbar. Open up your django shell and type the following command:

> from django.core.cache import cache
> cache.clear()

The Git Commit

Not interested in watching a 25 minute video about template fragment caching? Or just need the code? No problem! Here's the link to the entire GitHub commit: https://github.com/CodingForEverybody/learn-wagtail/commit/2766e207c9db99af5ff7dc16b91477bd7b786a97

Was this helpful to you?

Sharing is caring. Help the community by sharing this article.