\ ポイント最大11倍! /

【Django】静的ファイル(staticfiles)の配置・設定方法

  • 静的ファイルの設定方法がわからない!

このような方に向けて書きました。

静的ファイル(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の設定は不要です。

それでは、それぞれの設定方法を解説します。

すべてsettings.pyに記述します。

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ユーザー入力をスキップ
–clearSTATIC_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本番環境で静的ファイルを集める場所を指定
各設定項目の説明

開発環境と本番環境での扱い方の違いに注意しながら設定を行いましょう。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

karo@プログラマのアバター karo@プログラマ プログラマ

「書くことで人の役にたつ」をモットーに活動中。
本職はプログラマで、Pythonが得意。
基本情報技術者試験合格。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)