A Comprehensive Guide to Django Caching — SitePoint

By admin
In this article, you’ll get a comprehensive understanding of caching in

Django
PRODUCT

and web development as a whole. You’ll learn about what caching is, the benefits of caching, how to set up caching in

Django
FAC

, the backend systems that

Django
ORG

supports, and the best practices of caching.

By the end of the article, as a backend web developer, you’ll have a solid understanding of caching and how you can implement it in your Django projects for the best performance.

The Django framework is one of the most popular backend frameworks used by web developers

these days
DATE

. As a developer, building web applications with high performance should be

one
CARDINAL

of the goals on your list. So building a web application in Django for high performance shouldn’t be a hassle, since

Django
ORG

comes with a caching framework that allows you to use various caching backends like in-memory cache, file-based cache, database cache, and more.

Introduction to Django Caching

Caching in web development is a technique used by web developers to improve the performance of web applications. Every web application possesses resources that its users consistently desire to utilize. A resource could be anything from a straightforward web page to data stored in a database. Caching plays a significant role in maximizing the speed at which resources are accessed.

Common caching scenarios and use cases

The

Django
LAW

caching framework provides a wide range of scenarios and use cases that enable a developer to cache frequently accessed data. The following are the common caching scenarios:

Page Caching . This is a scenario where frequently visited pages on a site are entirely cached. The application fetches the cached versions of the pages and renders them when a request is made, as opposed to creating the content of the page from scratch.

Database Query Caching . Database query caching is a good approach for applications that depend on frequently requesting the database for information. A series of requests can be satisfied by the same piece of cached data without the need to hit the database, hence lowering database hits and speeding up server response time.

Session and Authentication Caching. Caching may be used to offer a streamlined user experience and a quicker response time. Since cached data will enable users to move easily across the authenticated sections of an application, caching authentication and session details can help to reduce redundant authentication operations.

Benefits of

Django
PRODUCT

caching

Caching has grown more advantageous to web developers in this modern environment where data is of the essence and speed is more essential. These are some of the benefits of caching:

Improved Performance . Caching enhances the performance of web applications by reducing server load. When the server gets requests from the application, Caching ensures that some requests are satisfied using previously cached data. This prevents the server from having to conduct those operations from scratch. As a result, the users’ experience is improved overall, and reaction times are sped up.

Reduced response time . Caching minimizes response time by reducing database hits. Caching enables the data to be fetched from a convenient location rather than directly from the database each time it is needed. Since some data need pricey calculations that can take some time to complete, fetching data every time it is needed from the database might not be the best choice for all data. By saving the data and promptly making it available whenever needed, caching saves

the day
DATE

.

Resource Optimization. Caching data or resources in a web application, allows resources to be accessible and retrievable without performing repetitive operations that output the same resources.

Setting up A Django Project

The main tasks in this section are to create the virtual environment and install the required modules for the project. To create the virtual environment, enter this command in your terminal:

$ python -m

venv
ORG

project

All the modules for the project will be installed inside this environment, so to start using it, we need to activate it.

On

Windows
PRODUCT

use this:

$ . \ project \ Scripts \ activate

And on macOS or

Linux
PRODUCT

, use this:

$ source project/bin/activate

Before we implement caching, the

first
ORDINAL

thing to do is set up a Django project. So let’s

first
ORDINAL

install

Django
PRODUCT

. Open your terminal, and run this command:

$ pip install django

After successfully installing

Django
PRODUCT

, let’s create a Django project and application. To create a

Django
PRODUCT

project run:

$ django-admin

startproject cachedproject
PERSON

Navigate into the project’s folder. Here, we’ll create a Django application. Run this command:

$ cd cachedproject

And then run this:

$ python manage.py startapp cachedapplication

After successfully creating the project and the application, we have to register the application to the project. Open the settings.py file, and make the

INSTALLED_APPS
ORG

list look like this:

INSTALLED_APPS = [ ‘django.contrib.admin’ , ‘django.contrib.auth’ , ‘django.contrib.contenttypes’ , ‘django.contrib.sessions’ , ‘django.contrib.messages’ , ‘django.contrib.staticfiles’ , ‘cachedapplication’ , ]

Note: to use the application in your Django project, it must be registered in the

INSTALLED_APPS
ORG

list.

Now, to verify that the

Django
ORG

framework has been installed successfully, let’s test it. In the terminal, run this command:

$ python manage.py runserver

Make sure you get the output pictured below.

Now copy the URL and paste it into the web browser. The expected output is pictured below.

Note: you can read more about quickly starting a

Django
PRODUCT

project and a

Django
ORG

app on

SitePoint
ORG

.

Configuring Different Caching Settings in settings.py

To use caching, we need to configure it in our

Django
PRODUCT

project, so in this section, we’ll look at how we can configure different caching systems available in

Django
PRODUCT

.

Local memory caching

As its name implies,

Local Memory Cache
PERSON

, sometimes abbreviated as

locmem
PERSON

, stores cached data in the

RAM
ORG

of the hosting machine.

Django automatically uses local memory caching as the default caching system if you don’t provide an alternate caching mechanism in your settings.py file. Its thread-safe, quick, and responsive caching technique is notable.

Local Memory Cache is less appropriate for use in production environments, since it includes a per-process mechanism that prevents any kind of cross-process caching and makes individual processes maintain separate private cache instances. It’s still a good choice, nevertheless, for development.

To configure local memory caching in your application, add the following code in the settings.py file:

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

File-based caching

In file-based caching, each cache value is serialized and kept separately in a file when caching. It’s useful for small-scale applications or where memory-based caching is not practical.

The downside of this caching system is that it’s relatively slower compared to memory-based caching.

To configure file-based caching in your application, add the following code in the settings.py file:

CACHES = { "default" : { "BACKEND" : "django.core.cache.backends.filebased.

FileBasedCache
ORG

" , "LOCATION" : "/var/tmp/django_cache" , } }

If you’re on

Windows
PRODUCT

, make sure you start the location’s path with the respective drive letter like this:

CACHES = { "default" : { "BACKEND" : "django.core.cache.backends.filebased.

FileBasedCache
ORG

" , "LOCATION" : "

C:/my
WORK_OF_ART

/path-to/file" , } }

Database caching

Apart from storing caches in files and hosting the machine’s

RAM
ORG

,

Django
ORG

also provides the ability to store the cache in a database.

This works best if you’ve got a fast, well-indexed database server.

To use database caching in your application, add the following code inside the settings.py :

CACHES = { "default" : { "BACKEND" : "django.core.cache.backends.db.

DatabaseCache
ORG

" , "LOCATION" : "my_cache_table" , } }

Use the following command to construct the database table mentioned in the setup above before using the cache:

python manage.py createcachetable

The command above creates a table in the database in a proper format that

Django
ORG

’s database cache system expects. The name of the table is taken from the

LOCATION
ORG

. In this case, the table’s name will be my_cache_table .

Memcached caching

Memcached is an in-memory caching system that’s used by web developers even in several popular companies to reduce database access and increase site performance.

In contrast to the locmem cache, Memcached operates as a daemon, which implies that the Memcached server runs as a background process, independently of any direct user interaction. Memcached must therefore be installed separately on your machine. Then in your Django application, install and configure

one
CARDINAL

of its bindings, such as

pylibmc
ORG

or

pymemcache
ORG

, to use Memcached.

A Django application can be linked to a Memcached daemon by adding the cache settings, location, IP address, and other details, as shown below:

CACHES = { "default" : { "BACKEND" : "django.core.cache.backends.memcached.

PyMemcacheCache
ORG

" , "LOCATION" : "

127.0.0.1:11211
DATE

" , } }

Memcached technology is especially suited for applications with high read or query loads, as it was designed for fast data storage and retrieval.

The downside of Memcached is that, since the data is stored in memory, it will be lost if your server crashes.


Redis

Redis
ORG

is an in-memory database that can be used for caching. It caches data using the

Redis
ORG

in-memory data storage. Redis is renowned for its quickness and adaptability, making it a great option for distributed systems and high-performance caching.

To cache data using

Redis
ORG

in your application, you need a

Redis
ORG

server running either locally or on a remote machine. To set up Redis on your machine, read the

Redis
ORG

getting started guide.

After setting up the

Redis
ORG

server, you’ll need to install Python bindings for

Redis
ORG

. Use this command to install it:

$ pip install django-redis

The redis-py interface is the binding supported natively by Django or using the django-redis and redis packages.

To configure Redis caching in your application, given that your Redis server is running on localhost (127.0.0.1), port=6379 , add the following code in the settings.py :

CACHES = { "default" : { "BACKEND" : "django.core.cache.backends.redis.

RedisCache
ORG

" , "LOCATION" : "redis://127.0.0.1:6379" , } }

Redis’ complexity and reliance on outside services are its trade-offs. Redis installation and configuration could be trickier than with certain other cache backends. It needs a

second
ORDINAL

server and upkeep when online. Redis usage creates a reliance on an outside service. Your application’s caching capabilities may be affected if

Redis
ORG

has problems or goes down.

Performing Caching in Django Using Redis

Okay, that’s enough theory. In this section, we’ll demonstrate how to perform caching in a Django application. We’ll focus on

three
CARDINAL

forms of caching:

view caching

template fragment caching

per-site caching

But before we perform each caching form in detail, let’s

first
ORDINAL

set up the project properly. We’ll create, register, and populate the models, configure the application’s URLs, create a template, install the

Django
PRODUCT

debug toolbar, and configure it.

Inside the cachedapplication app, open the models.py file and make it look like this:

from django . db import models class Programmer ( models . Model ) : name = models .

CharField
ORG

( max_length =

50
CARDINAL

) dob = models .

CharField
ORG

( max_length =

20
CARDINAL

) language = models .

CharField
ORG

( max_length =

20
CARDINAL

) quote = models .

CharField
ORG

( max_length =

150
CARDINAL

) def __

str
PERSON

__ ( self ) : return f" { self . name } "

Next, open the admin.py file and paste this code:

from django . contrib import admin from . models import

Programmer
ORG

admin . site . register ( Programmer )

This code snippet registers the model Programmer in the

Django
ORG

admin dashboard.

Before populating the models, let’s do some migrations. In the terminal, run this:

$ python manage.py makemigrations

And also run this:

$ python manage.py migrate

In Django, we can populate our models in

two
CARDINAL

ways: via the terminal, and via the admin dashboard. But for simplicity’s sake, we’ll use the admin dashboard. Since the admin dashboard is for the superuser only, we need to create one. In the terminal, run the following command:

$ python manage.py createsuperuser

This command will prompt you to enter superuser details like username, email, and the

two
CARDINAL

passwords.

After successfully creating the superuser, fire up the local server, and in your browser enter this URL: http://127.0.0.1:8000/admin/ . The image below shows the page you’ll be taken to.

To log in, provide the superuser credentials, and once you’re in, populate the models with data, as pictured below.

Inside the application, create a templates folder, and inside it create a list_all.html file. For now, leave the HTML file empty. Open the views.py file and make it look like this:

from django . shortcuts import render from . models import Programmer def home ( request ) : programmers = Programmer . objects . all ( ) context = { ‘programmers’ : programmers } return render ( request , ‘list_all.html’ , context )

Now let’s register the home view in the project’s urls.py file. Inside the cachedproject folder, open the urls.py file and paste this code:

from django . contrib import admin from django . urls import path , include from cachedapplication import views

urlpatterns
PERSON

= [ path ( ‘admin/’ , admin . site . urls ) , path ( ‘home/’ , views . home , name = ‘home’ ) , ]

Now open the list_all.html file and paste the following code:

<! DOCTYPE html > < html lang = " en " > < head > < meta charset = " UTF-8 " > < meta name = " viewport " content = " width=device-width, initial-scale=1.0 " > < title > Caching </ title > < link href = " https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.4.2/mdb.min.css " rel = " stylesheet " /> </ head > < body > < div class = " container py-5 " > < table class = " table " > < thead > < tr > < th > Name </ th > < th > DOB </ th > < th > Language </ th > < th > Quote </ th > </ tr > </ thead > < tbody > {% for programmer in programmers %} < tr > < td > {{programmer.name}} </ td > < td > {{programmer.dob}} </ td > < td > {{programmer.language}} </ td > < td > {{programmer.quote}} </ td > </ tr > {% endfor %} </ tbody > </ table > </ div > </ body > </ html >

Let’s install a

Django
PRODUCT

debug toolbar. This is a

Python
ORG

package that helps developers monitor the performance of their

Django
PRODUCT

applications, providing detailed information about database queries, HTTP requests, template rendering times, and more. So in your terminal, enter this command:

pip install django-debug-toolbar

To configure the django-debug-toolbar , open the settings.py file and edit the

INSTALLED_APPS
ORG

list to look like this:

INSTALLED_APPS = [ ‘django.contrib.admin’ , ‘django.contrib.auth’ , ‘django.contrib.contenttypes’ , ‘django.contrib.sessions’ , ‘django.contrib.messages’ , ‘django.contrib.staticfiles’ , ‘cachedapplication’ , ‘debug_toolbar’ , ]

Add the debug toolbar to the

MIDDLEWARE
ORG

list:

MIDDLEWARE = [ ‘debug_toolbar.middleware.DebugToolbarMiddleware’ , ]

Make the debug toolbar middleware come right after this:

django . middleware . csrf . CsrfViewMiddleware

It should also come before this:

django . contrib . auth . middleware . AuthenticationMiddleware

Add the Redis cache configurations as follows:

CACHES = { "default" : { "BACKEND" : "django_redis.cache.

RedisCache
ORG

" , "LOCATION" : "redis://127.0.0.1:6379/1" , "OPTIONS" : { "CLIENT_CLASS" : "django_redis.client.DefaultClient" , } } }

Also, add this code to the to the settings.py file:

INTERNAL_IPS = [ ‘127.0.0.1’ , ]

Finally, let’s configure the debug toolbar URLs in the urls.py file. Just below the imports, add this line of code:

import debug_toolbar

Inside the

urlpatterns
ORG

list add this code:


urlpatterns
PERSON

= [ path ( ‘__debug__/’ , include ( debug_toolbar . urls ) ) , ]

Having reached this far, we’re good to go. Run the server and paste this URL into your browser:

http://127.0.0.1:8000
NORP

/home/ . The image below shows the page we get.

Every time you run the application using this view, it will make

SQL
ORG

queries. In this case,

three
CARDINAL

queries have taken

2.60ms
PRODUCT

. So to avoid making

SQL
ORG

queries for the same data every time, we’ll implement the view caching.

View caching

As the name suggests, view caching caching involves caching the results of individual Django views. In this section, we’ll implement the view caching. To do this, we’ll make a few modifications to the view.py file. Open it and add this import:

from django . views . decorators . cache import cache_page

Right above the view, also add this decorator:

@cache_page (

60
CARDINAL

* 15 )

(

60
CARDINAL

*15) is the argument passed to @cache_page . It represents the cache timeout in

seconds
TIME

. The home view will be cached for

15 minutes
TIME

.

Now visit the same view and refresh the page. We’ll get the result pictured below.

In the image above, we can see that there are

0
CARDINAL

SQL queries performed, as data is being fetched from the cache. This helps reduce the load on the server by serving cached content to users.

Template fragment caching

This caching involves caching specific parts of a template in your project. When your template has portions with heavy calculations, template fragment caching comes in handy. To implement this caching, we use these tags: {% load cache %} , {% cache %} , and {% endcache %} . The {% cache %} tag takes

two
CARDINAL

arguments: the cache timeout, and a unique cache key for identifying a specific cached fragment.

Now try running the project before implementing this caching technique. the image below shows what we’ll get.

The total time is 220.26ms, and

three
CARDINAL


SQL
ORG

queries are performed in 7.75ms.

Now let’s implement the caching technique. We’ll cache the <div> portion of the template. Open the templates/list_all.html , and modify it to look like this:

{% load cache %} <! DOCTYPE html > < html lang = " en " > < head > < meta charset = " UTF-8 " > < meta name = " viewport " content = " width=device-width, initial-scale=1.0 " > < title > Caching </ title > < link href = " https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.4.2/mdb.min.css " rel = " stylesheet " /> </ head > < body > {% cache

500
CARDINAL

programmers %} < div class = " container py-5 " > < table class = " table " > < thead > < tr > < th > Name </ th > < th > DOB </ th > < th > Language </ th > < th > Quote </ th > </ tr > </ thead > < tbody > {% for programmer in programmers %} < tr > < td > {{programmer.name}} </ td > < td > {{programmer.dob}} </ td > < td > {{programmer.language}} </ td > < td > {{programmer.quote}} </ td > </ tr > {% endfor %} </ tbody > </ table > </ div > {% endcache %} </ body > </ html >

On top of the file, we’re loading the cache via {% load cache %} and we’ve enclosed the div portion with {% cache

500
CARDINAL

programmers %} and {% endcache %} .

If you run the project again you will get the result pictured below.

In the image above, we can see that the results have improved after the caching has been implemented.

Per-site caching

Per-site caching is also known as whole-site caching. It involves caching the whole site’s pages. To implement it, you need to add these middleware configurations in the settings.py file:

MIDDLEWARE = [ ‘

django.middleware.cache
ORG

.UpdateCacheMiddleware’ , ‘

django.middleware.common
PERSON

.CommonMiddleware’ , ‘

django.middleware.cache.FetchFromCacheMiddleware’
ORG

, ]

And also add these lines:

CACHE_MIDDLEWARE_ALIAS = ‘ ‘

CACHE_MIDDLEWARE_SECONDS
ORG

=

600
CARDINAL

CACHE_MIDDLEWARE_KEY_PREFIX = ”

Conclusion

In conclusion, understanding caching in

Django
ORG

is essential for web developers looking to create high-performance web applications. This article has provided a comprehensive guide to caching in

Django
ORG

, covering topics such as the benefits of caching, setting up caching in

Django
ORG

, and the best practices for implementation. Armed with this knowledge, backend web developers can confidently incorporate caching into their

Django
PRODUCT

projects to optimize performance.

If you enjoyed this article, check out some more Django articles on

SitePoint
ORG

.