Python Shikhi. Learn with Fun


image

Django Static Version Change Dynamically to update Cache.


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')