- 静的ファイルの設定方法がわからない!
このような方に向けて書きました。
静的ファイル(static files)とはクライアント側に直接配布されるファイルのことで、具体的には次のようなものです。
- CSSファイル
- JavaScriptファイル
- 画像ファイル
- フォントファイル
テンプレートHTMLやモデルのクエリ結果など、リクエストに応じて異なる結果が返る動的ファイルとの対比で語られます。
一番の違いは、静的ファイルはWebサーバー(Nginxなど)で直接配信されるのに対して、動的ファイルは本番環境でもDjangoで生成される点です。
本記事では静的ファイルの設定方法をまるっとお伝えします。
静的ファイルを配置する場所
静的ファイルの配置場所は、大きく二種類に分けられます。
- プロジェクト全体で使用するファイル
- アプリ固有のファイル
それぞれ、解説します。
プロジェクト全体で使用するファイル
プロジェクト全体で使う静的ファイルは、プロジェクトルート配下のstaticディレクトリに配置します。
例えばstatic/style.cssのような形ですね。
my_project/
├── manage.py
├── static/
│ └── style.css # プロジェクト全体で使用するCSS
ファイルの種類ごとにディレクトリを掘ってあげたほうが、後々の管理上は便利です。
my_project/
├── manage.py
├── static/
│ └── css/
│ └── style.css # プロジェクト全体で使用するCSS
ちなみにこの保存場所はsettings.pyで設定しておく必要があります。
STATIC_URL = "/static/"
このSTATIC_URL変数の設定方法は、記事の後半で解説します。
アプリ固有のファイル
アプリ内でしか使わない静的ファイルの格納先は以下の通りです。
my_project/
├── manage.py
├── app/
│ ├── models.py
│ └── static/
│ └── app/
│ └── style.css # 直接static/app/にstyle.cssを配置
ここで注意したいのが、static配下にアプリ名を付けたディレクトリを配置すること。
つまりapp/static/style.css
ではNGです。
なぜならcollectstaticコマンドでアプリの静的ファイルが一箇所に集められる時に、このディレクトリがないとファイル名が衝突してしまう恐れがあるためです。
※ collectstaticコマンドの挙動についてはこちらで解説します
my_project/
├── manage.py
├── app/
│ ├── models.py
│ └── static/
│ └── app/
│ └── css/
│ └── style.css
先ほどの「プロジェクト全体で使用するファイル」と同様、静的ファイルの種類ごとにディレクトリを切っておくと管理が簡単になります。
なお、ディレクトリを切る際のファイルの種類は以下のような基準で行うと良いです。
ディレクトリ名 | 格納するファイルの種類 |
---|---|
css | スタイルシート |
js | フロントエンドのスクリプト |
images | 画像ファイル |
fonts | ウェブフォント、アイコンフォント |
静的ファイル配信のための設定
静的ファイルの配信には、次の設定が必要です。
- STATICFILES_DIRS
- STATIC_URL
- STATIC_ROOT
このうちSTATIC_ROOTは本番環境(DEBU=False)だけで設定すれば大丈夫です。
本番環境では静的ファイルを一箇所にまとめなければならず、そのためにSTATIC_ROOTを設定します。
一方の開発環境(DEBUG=True)では、Djangoの開発サーバーでは各所に散らばった静的ファイルを自動的に集めて配信してくれるのでSTATIC_ROOTの設定は不要です。
それでは、それぞれの設定方法を解説します。
STATIC_URL
STATIC_URL = "/static/"
STATIC_URLでは静的ファイルのURLパスを指定します。
実際に生成されるURLで確認
例えばblogアプリディレクトリに/static/blog/images/logo.pngを配置した場合、画像を配信するURLは以下のようになります。
http://127.0.0.1:8000/static/blog/images/logo.png
極端な例として、STATIC_URL = "/sample/"
としたら次のようになるわけです。
http://127.0.0.1:8000/sample/blog/images/logo.png
テンプレートHTMLへの影響
先ほど説明したように、STATIC_URLの設定によって静的ファイルにはURLが付与されます。
そこで、次のようなテンプレートHTMLを考えてみましょう。
{% static %}
<img src="{% static 'blog/images/logo.png' %}" alt="Logo">
STATIC_URL = “/static/”とした場合には、テンプレートHTMLがレンダリングされた段階で次のように変換されます。
<img src="http://127.0.0.1:8000/static/blog/images/logo.png" alt="Logo">
Djangoでは {% static %} というテンプレートタグを使って、ファイルパスからURLへの変換が行われます。
このように、ファイルパスからURLへの変換するために必要な設定がSTATIC_URLです。
STATICFILES_DIRS
STATICFILES_DIRS = [BASE_DIR / "static"]
STATICFILES_DIRSでは、プロジェクト全体で共通して使う静的ファイルを格納する場所を指定します。
いわばグローバル的な静的ファイルというイメージです。
全体の挙動としては、次のとおりになります。
- STATICFILES_DIRSで指定された場所と各アプリケーションのstaticディレクトリの両方から静的ファイルを収集
- 同名のファイルがあれば、STATICFILES_DIRSで指定した場所のファイルを優先
例えば以下のようにstyle.cssというファイル名が複数あった場合、STATICFILES_DIRSで指定された場所にあるstyle.cssが優先されます。
my_project/
├── manage.py
├── my_project/
│ └── settings.py
├── static/ # STATICFILES_DIRSで指定された場所
│ └── css/
│ └── style.css # ここにあるstyle.cssが優先される
├── app_one/
│ ├── models.py
│ └── static/
│ └── app_one/
│ └── css/
│ └── style.css # 無視される
└── app_two/
├── views.py
└── static/
└── app_two/
└── css/
└── style.css # 無視される
このようにプロジェクト全体で共通利用する静的ファイルがあるならば、settings.pyにSTATICFILES_DIRSを定義します。
STATIC_ROOT
STATIC_ROOT = BASE_DIR / "staticfiles"
Djangoで本番環境に移行する時には、collectstaticコマンドというものを実行します。
python manage.py collectstatic
このコマンドは、プロジェクト内のすべての静的ファイルを一箇所に集めるものです。
コマンドを実行するとstaticfilesディレクトリが作成されて、次のような状態になります。
my_project/
├── manage.py
├── my_project/
│ └── settings.py
├── static/ # STATICFILES_DIRSで指定された場所
│ ├── css/
│ │ └── style.css
│ └── images/
│ └── logo.png
├── staticfiles/ # collectstaticでここにファイルが集められる (STATIC_ROOT)
│ ├── css/
│ │ └── style.css # STATICFILES_DIRSのファイル
│ ├── images/
│ │ └── logo.png # STATICFILES_DIRSのファイル
│ ├── app_one/
│ │ └── css/
│ │ └── style.css # app_oneのstaticディレクトリのファイル
│ └── app_two/
│ └── css/
│ └── style.css # app_twoのstaticディレクトリのファイル
├── app_one/
│ ├── models.py
│ └── static/
│ └── app_one/
│ └── css/
│ └── style.css
└── app_two/
├── views.py
└── static/
└── app_two/
└── css/
└── style.css
collectstaticが必要な理由は、静的ファイルはDjangoを通さずに直接Webサーバーで配信されるため、すべての静的ファイルを一箇所に集めておく方が効率的で、管理がしやすいからです。
これによりWebサーバーは静的ファイルを高速に提供できるので、キャッシュの利用なども容易になります。
本番前に実行するcollectstaticコマンドについて
ここからはSTATIC_ROOTで指定したディレクトリに静的ファイルをまとめるcollectstaticコマンドについて深掘りして解説します。
コマンドの実行方法
基本のコマンドは以下になります。
python manage.py collectstatic
いくつかオプションが用意されているので、状況に応じて使い分けましょう。
オプション | 効果 |
---|---|
–noinput | ユーザー入力をスキップ |
–clear | STATIC_ROOT内をクリアしてから実行 |
–dry-run | 収集される予定のファイルを見るだけ |
例えば複数オプションをつける場合には、次のようにコマンドを実行します。
python manage.py collectstatic --noinput --clear
シェルスクリプトでデプロイ時に自動的にcollectstaticする
デプロイ作業をシェルスクリプトに落とし込んでおけば、collectstaticコマンドも自動化できます。
以下は簡単なシェルスクリプト例です。
#!/bin/bash
# デプロイの開始を表示
echo "Starting deployment..."
# Djangoのディレクトリへ移動
cd /path/to/your/django/project || exit
# 仮想環境をアクティベート (必要に応じて)
source /path/to/your/virtualenv/bin/activate
# collectstaticコマンドを実行
python manage.py collectstatic --noinput
# デプロイ完了を表示
echo "collectstatic completed."
# その他のデプロイ作業(例: サービスの再起動など)
# sudo systemctl restart nginx
# sudo systemctl restart gunicorn
シェルスクリプトを作成したら、実行権限を付与しましょう。
chmod +x deploy.sh
最後にシェルスクリプトを実行します。
./deploy.sh
まとめ
この記事では、Djangoで静的ファイルを管理・配信するための設定方法を紹介しました。
変数名 | 内容 |
---|---|
STATIC_URL | 静的ファイルのURLを指定 |
STATICFILES_DIRS | 共通の静的ファイルのディレクトリを指定 |
STATIC_ROOT | 本番環境で静的ファイルを集める場所を指定 |
開発環境と本番環境での扱い方の違いに注意しながら設定を行いましょう。
コメント