背景

在django中,

默认情况, 通常我们在模板里引用静态文件都是这样的

<link rel="stylesheet" href="{% static 'css/main.css' %}">

但是有时候,因为浏览器缓存策略,或者使用的cdn缓存策略等原因,会导致我更新了这个css文件后,打开网页css文件还是以前的

我想到的第一个方法就是 添加个 v=时间戳 这样的办法, 比如:

<link rel="stylesheet" href="{% static 'css/main.css?v=2024-12-30' %}">

但是这样有个弊端, 我可能代码里有许多的资源文件,不可能手动去修改, 所以想找一个更优雅的方式

在网上找了一下,发现了几个办法:

1、 在 settings.py 中配置一个字段 VERSION, 然后 {% static 'css/main.css?v={{VERSION}}' %} 这个坏处是, 每次部署后, 都需要修改这个版本号, 很麻烦

2、使用 django.contrib.staticfiles.storage.ManifestStaticFilesStorage 经过测试,用这个最省事

步骤

1、 在 settings.py 中配置:

DEBUG = False # 这个必须为False,否则不会生效(否则是开发模式,开发模式不会在对文件名进行hash)
STORAGES = {
    # 其他配置...

    # 重点就是这个 staticfiles 配置 (django 新版都是这样配置)
    "staticfiles": {
        "BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
    },
}

提示: 网上很多办法都是设置 STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage' ,但是我想说,这个办法已经过时了, 至少在 django 5.x 上 不生效

2、执行 python manage.py collectstatic --noinput

3、搞定,打开浏览器,查看源码,就可以看到

   <link rel="stylesheet" href='/static/css/main.5926df2150bc.css'>

.5926df2150bc 就是django 自动添加的(当原始文件main.css的内容改变后,执行 python manage.py collectstatic --noinput, 5926df2150bc 就会变成别的,否则每次都不会改变 ), 我们在 模板里,不需要做什么修改,还是写 {% static 'css/main.css' %} 就行

额外的提示

其实我第一次按照这个步骤配置完成后,启动项目会报错 500,但是 django 却没有告诉我为什么有这个错误,我把 DEBUG 设置为 True 后,没有错误了,说明这个错误只有在 DEBUG 设置为 False才会出现。所以就进入死循环了,根本没办法找到具体错误在哪里

经过一番搜寻,发现 可以给 django 配置 DEBUG_PROPAGATE_EXCEPTIONS=True , 这样以后, 在生产模式也可以打印更多错误信息

当我添加了 DEBUG_PROPAGATE_EXCEPTIONS=True, 后,我才发现, 我的错误是因为 我引用了一个不存在的css文件 <link rel="stylesheet" href="{% static 'css/home.css' %}">

这个 home.css 文件不存在,所以 导致 django的 ManifestStaticFilesStorage 引发了错误,但这个错误在生产模式(DEBUG=False)又没有打印出来,它只是提示500

还好 DEBUG_PROPAGATE_EXCEPTIONS=True 可以打印更多错误信息

参考

https://www.chenshaowen.com/blog/control-of-static-file-version-in-django.html

https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#manifeststaticfilesstorage