Use CachedStaticFilesStorage instead of default storage to collect files with md5 filenames.

To achieve this, set next in settings.py:

STATICFILES_STORAGE = "django.contrib.staticfiles.storage.CachedStaticFilesStorage"

Run collectstatic

$ python3 manage.py collectstatic --noinput

You will note that in addition to regular files coping into static serve directory, collectstatic will also create cloned files with md5 name postfix: e.g. you will see:

Post-processed 'build.js' as 'build.d5421e896de1.js'

And if you list your serve dir:

$ ls /root/maketips/serve/
build.js build.d5421e896de1.js ...

Next you should include your file in html in this way:

{% load static %}
<script src="{% static 'build.js' %}"></script>

It is important that in Django 1.10 you can use {% load static %} but in older versions you should use {% load static from staticfiles %} instead.

Then on production environment (where DEBUG is False) you will have next links to static: <script src="/static/build.d5421e896de1.js"></script>. And each time when you modify file in new release and recollect it, all caches (Browser, CDN, etc) will fetch new file immidiately.

Urls for html static resolver will be calculated once and stored in Django cache. If you did not configure any caches in settings.py, the default Local-memory caching will be used. It is ok, but you also should know that after updating static you also need to restart your Django instance to clear Local-memory cache.

Longer static caching

Now, when you can guarantee that different static files will have different names you can tell browsers to cache static files for a longer period, e.g. for 1 year. Here is nginx example:

location /static {
    alias /root/maketips/serve;
    expires 1y;
    access_log off;
    add_header Cache-Control "public";
}

static versioning