Django Static Version Change Dynamically to update Cache.
Published Date: Nov. 19, 2024
To ensure that changes in your CSS or other static files are updated in the browser without manually clearing the cache, you can append a version identifier or hash to your static file URLs. This is commonly achieved using Django's ManifestStaticFilesStorage
or by appending a version number.
Option 1: Use ManifestStaticFilesStorage
1. Update STATICFILES_STORAGE
: In your settings.py
, set the static files storage to ManifestStaticFilesStorage
:
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
This will append a hash of the file's contents to the file names when running collectstatic
. For example, style.css
might become style.abc123.css
. When the file changes, the hash will change, invalidating the browser cache.
2. Run collectstatic
: Whenever you update your static files (CSS, JavaScript, etc.), run:
python manage.py collectstatic
<link rel="stylesheet" href="{% static 'css/style.css' %}">
Option 2: Manually Add a Version Query Parameter:
If you don't want to use hashed file names, you can append a version number to static file URLs.
1. Customize the static
Template Tag: In your template, modify the static URL with the version parameter:
<link rel="stylesheet" href="{% static 'css/style.css' %}?v={{ STATIC_VERSION }}">
2. Define a Version in settings.py
:
STATIC_VERSION = '1.0.1'
3. Pass STATIC_VERSION
to Your Template Context: You need to ensure the STATIC_VERSION
variable is available in your templates. Add it globally using a context processor.
Create a new file called context_processors.py
in one of your apps:
from django.conf import settings
def static_version(request):
return {'STATIC_VERSION': settings.STATIC_VERSION}
Add this context processor to your TEMPLATES
setting in settings.py
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'your_app_name.context_processors.static_version',
],
},
},
]
4. Increment STATIC_VERSION
: When you make changes to the CSS, just update the STATIC_VERSION
in settings.py
. This will ensure browsers fetch the updated file.
Option 3: Use a Middleware to Add Cache-Control
If you prefer controlling caching behavior directly through HTTP headers, you can set a Cache-Control
header.
1. Create a Custom Middleware:
from django.utils.cache import patch_cache_control
class CacheControlMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if request.path.startswith('/static/'):
patch_cache_control(response, max_age=0, must_revalidate=True)
return response
2. Add the Middleware in settings.py
:
MIDDLEWARE.append('path.to.CacheControlMiddleware')