首先了解一些背景信息。我使用以下“技巧”来防止浏览器缓存静态文件(CSS、JS等):
<script src="{{ STATIC_URL }}js/utils.js?version=1302983029"></script>
当版本字符串在后续页面加载时发生更改,它会使浏览器重新从服务器获取静态文件。(查询"css缓存"以了解此技巧的文章。)
我希望浏览器获取最新版本的静态文件,但我也希望在文件未更改时允许浏览器缓存。换句话说,我希望只有在静态文件已更新时才更改版本字符串。我还希望自动生成版本字符串。
为此,我使用静态文件的最后修改时间作为版本字符串。我正在使用一个自定义模板标签来实现这一点:
<script src="{% versioned_static 'js/utils.js' %}"></script>
以下是模板标签的工作原理:
import os.path
from django import template
from django.conf import settings
class VersionedStaticNode(template.Node):
...
def render(self, context):
# With the example above, self.path_string is "js/utils.js"
static_file_path = os.path.join(settings.STATIC_ROOT, self.path_string)
return '%s?version=%s' % (
os.path.join(settings.STATIC_URL, self.path_string),
int(os.path.getmtime(static_file_path))
)
要获取静态文件的最后修改时间,我需要知道其在系统中的文件路径。我通过连接
settings.STATIC_ROOT
和该静态文件相对于该静态根目录的相对路径来获得此文件路径。这对于生产服务器来说非常好,因为所有静态文件都被收集在STATIC_ROOT
下。然而,在开发服务器上(使用manage.py runserver命令),静态文件不会被收集在
STATIC_ROOT
下。那么在开发中运行时如何获取静态文件的文件路径呢?(为了澄清我的目的:我想避免的缓存情况是浏览器使用新HTML和旧CSS/JS的不匹配。在生产中,这可能会极大地困惑用户;在开发中,这可能会困扰我和其他开发人员,并迫使我们经常刷新页面/清除浏览器缓存。)
finders.find()
就是我需要的。谢谢,我的模板标签现在可以工作了!稍后我会发布可工作的代码。 - S. Kirby