最初にいくつかの背景。静的ファイル (CSS、JS など) の望ましくないブラウザー キャッシュを防ぐために、次の「トリック」を採用しています。
<script src="{{ STATIC_URL }}js/utils.js?version=1302983029"></script>
その後のページ読み込みでバージョン文字列が変更されると、ブラウザはサーバーから静的ファイルを再取得します。(このトリックに関する記事については、Google の「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 の不一致を使用するブラウザです。本番環境では、これはユーザーを大いに混乱させる可能性があります。開発では、これは私と他の開発者を混乱させる可能性があり、頻繁にページを更新したり、ブラウザのキャッシュをクリアしたりしてください。)