Сначала немного фона. Я использую следующую «хитрость» для предотвращения нежелательного кеширования браузером статических файлов (CSS, JS и т. Д.):
<script src="{{ STATIC_URL }}js/utils.js?version=1302983029"></script>
Когда строка версии изменяется при последующей загрузке страницы, браузер повторно выбирает статический файл с сервера. (Google "css caching" для статей об этой уловке.)
Я хочу, чтобы браузер получал последнюю версию статического файла, но я также хочу разрешить кэширование в браузере, когда файл не изменился. Другими словами, я хочу, чтобы строка версии изменялась тогда и только тогда, когда статический файл был обновлен. Я также хотел бы автоматически генерировать строку версии.
Для этого я использую время последнего изменения статического файла в качестве строки версии. Я делаю пользовательский тег шаблона для этого:
<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
.
Однако на сервере разработки (где используется команда runserver manage.py) статические файлы не собираются в STATIC_ROOT
. Так как же получить путь к файлу статического файла при запуске в разработке?
(Чтобы прояснить мою цель: ситуация с кэшированием, которую я хочу избежать, заключается в том, что браузер использует несоответствие нового HTML и старого CSS / JS. На производстве это может сильно запутать пользователей; в процессе разработки это может сбить меня с толку и других разработчиков и вынуждает нас часто обновлять страницы / очищать кеш браузера.)