スマホ実機・本番環境でもキャッシュを100%破壊する方法をご紹介します。
Django でスタイルを調整していると、CSS が反映されないことはよく遭遇します。
特にスマホ(iPhone Safari)は静的ファイルを強力にキャッシュするので、リロードしても古いCSSを返しがちです。(iPhoneは、スーパーリロードが実質使えない)
結論として、静的ファイルURLにキャッシュバスターを付け、環境ごとに生成方法を切り替える。
これだけで完全に解決できます。
前提知識
■ 原因:スマホは静的ファイルを強くキャッシュする
スマホでは、URLが変わらない限りCSSはキャッシュされ続けます。
- Safari は CSS / JS のキャッシュを長く保持する
- PC のような “スーパーリロード” がスマホには無い
- 同じ URL で提供される静的ファイルは更新されない
■ Settings構成(前提)
以下のように settings を環境ごとに分けている前提で進めます:
project/
│ ├── settings
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── development.py
│ │ └── production.pyこの構成について詳しくは、以下の記事をご覧ください。

■ 最適なキャッシュバスター戦略2つ
開発/本番で求められる挙動が違います。
そのため、バージョン生成方法を 2パターン に分けるのが合理的です。
▶ 開発環境(development.py)
毎回即反映させたい → time.time() を使う
# development.py
from .base import *
import time
STATIC_VERSION = int(time.time())- runserver の再起動ごとに値が変わる
- スマホ実機でも 100% 最新 CSS が反映される
- 「反映されないイライラ」が完全に消える
▶ 本番環境(production.py)
デプロイ単位で更新したい → Git のコミットIDを使う
# production.py
from .base import *
import subprocess
def get_git_hash():
try:
return (
subprocess.check_output(["git", "rev-parse", "--short", "HEAD"])
.decode()
.strip()
)
except Exception:
return "prod"
STATIC_VERSION = get_git_hash()- デプロイ(新しいコミット)ごとに自動でバージョン更新
- 本番キャッシュが無駄に破壊されず、高速性を維持
- ステージングやスマホ実機確認でも確実に更新される
▶ base.py にはデフォルト値だけ置く
# base.py
STATIC_VERSION = "dev"処理は environment-specific files に寄せ、base は “薄く保つ” のがベスト。
■ テンプレートは全環境共通
<link rel="stylesheet" href="{% static 'css/app.css' %}?v={{ STATIC_VERSION }}">これだけで OK。
裏側で STATIC_VERSION が環境ごとに自動で切り替わります。
■ まとめ
CSS が反映されない問題は、アプリ側の問題ではなく ブラウザキャッシュの仕様。
静的ファイルURLを環境ごとに変えれば、スマホでも本番でも 100% 最新スタイルが読み込まれる。
| 環境 | STATIC_VERSION | 意図 |
|---|---|---|
| development.py | int(time.time()) | 毎回キャッシュ破壊・即反映 |
| production.py | Git ハッシュ | デプロイ単位で確実に更新 |
UI 開発中のストレスが激減するので、Django プロジェクトでは必須のパターンと言っていいレベルです。

コメント