About Invalidating Django Page Cache
When you use @cache_page decorator for views, the cache key will be based on these variables:
- cache key base string (e.g. "views.decorators.cache.cache_page")
settings.CACHE_MIDDLEWARE_KEY_PREFIX- request method (e.g. "GET")
- hashed full URL
- a hash of predefined request headers
- request language code
- active timezone
Use the following utility function to delete such cache entry for a specific cached view:
def invalidate_cache_for_path(url_path):
from django.conf import settings
from django.core.cache import cache
from django.http import HttpRequest
from django.utils.cache import get_cache_key
website_url = getattr(settings, "WEBSITE_URL", "")
if not website_url:
return
parsed = urlparse(website_url)
key_prefix = getattr(settings, "CACHE_MIDDLEWARE_KEY_PREFIX", "")
# SECURE_PROXY_SSL_HEADER is set in production, so Django reads
# HTTP_X_FORWARDED_PROTO from META and returns the correct scheme.
dummy = HttpRequest()
dummy.path = url_path
dummy.META = {
"HTTP_HOST": parsed.netloc,
"HTTP_X_FORWARDED_PROTO": parsed.scheme,
}
deleted_keys = []
for lang_code, _ in settings.LANGUAGES:
dummy.LANGUAGE_CODE = lang_code
cache_key = get_cache_key(dummy, key_prefix=key_prefix)
if cache_key:
cache.delete(cache_key)
deleted_keys.append(cache_key)
For the decorator to work correctly, you also need these Django settings:
WEBSITE_URL(e.g. "https://www.djangotricks.com").SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")- without it, the dummy request produceshttp://, the URL hash is different, andget_cache_keyreturnsNone.LANGUAGESreduced to only those languages that you use for translations.
So if you have a view:
from django.shortcuts import render, get_object_or_404
from django.views.decorators.cache import cache_page
from django.contrib.auth.models import User
@cache_page(60 * 15) # Cache the view for 15 minutes
def user_profile_view(request, username):
user = get_object_or_404(User, username=username)
context = {
"user": user,
}
return render(request, "pages/user_profile.html", context)
And URL path:
from django.urls import path
from .views import user_profile_view
urlpatterns = [
path("users/<str:username>/", user_profile_view, name="user_profile"),
]
And that user changes their user information, you can invalidate the cache and make the page show fresh information with:
invalidate_cache_for_path(
reverse("user_profile", kwargs={"username": user.username})
)
Tips and Tricks Programming Caching Django 6.x Django 5.2 Django 4.2 Memcached Redis Cache
Django/Python Consulting
If you have a specific Django challenge or integration you'd like to solve, I'd be happy to help. Book a free 30-minute call to discuss your project, see if we're a good fit, and explore the best approach for your needs. After the call, you'll receive a tailored cost estimate based on what we discuss.
Also by me
Django Messaging
For Django-based social platforms.
Django Paddle Subscriptions
For Django-based SaaS projects.
Django GDPR Cookie Consent
For Django websites that use cookies.