ユーニックス総合研究所

  • home
  • archives
  • django-collectstatic

Djangoのcollectstaticで静的ファイルを華麗に集める

  • 作成日: 2021-08-03
  • 更新日: 2023-12-24
  • カテゴリ: Django

Djangoのcollectstaticで静的ファイルを集める

Djangoでは画像ファイルやCSSファイルなどのことを静的ファイルと表現します。
これらの静的ファイルは、開発時と本番時で扱いが違ってきます。

具体的には静的ファイルは、開発時にはDjangoが勝手に管理してくれますが、本番稼働時のサーバーでは静的ファイルを一か所のディレクトリに集めてWebサーバー側で管理させる必要があります。

一か所のディレクトリに静的ファイルを集めるコマンドがpython manage.py collectstaticです。
この記事ではcollectstaticの使い方について具体的に解説します。

STATIC_URL

STATIC_URLは今回のcollectstaticコマンドとの関連はありません。
STATIC_URLsettings.pyに定義される、静的ファイルのURL上の接頭辞です。
たとえば↓のようにSTATIC_URLを定義した場合、

STATIC_URL = '/static/'  

静的ファイルのURLは/static/core/img/ball.jpgなどのようになります。
STATIC_URL/assets/などに変更した場合は、URLは/assets/core/img/ball.jpgになります。

STATIC_ROOT

settings.pyに定義されるSTATIC_ROOTには、サーバー上のパスを設定します。
このパスには、collectstaticコマンドを実行した時に静的ファイルが集まります。
つまり↓のようなSTATIC_ROOTの場合、

STATIC_ROOT = '/var/sample.com/static/'  

collectstaticコマンドは/var/sample.com/static/以下に静的ファイルを収集します。

staticディレクトリ

Djangoではstaticというディレクトリは特別な意味を持ちます。
というのも、Djangoはアプリ以下に配置されたstaticディレクトリを暗黙的に管理するからです。
このstaticディレクトリ以下の静的ファイルは、collectstaticコマンドを実行したときに自動で収集されます。

static以外のディレクトリ

staticディレクトリ以外の名前のディレクトリを静的ファイルの格納場所として指定したい場合があります。
たとえばcoreアプリ以下にmyfileというディレクトリを作って、このディレクトリ以下に画像ファイルなどを配置する場合です。
そういう場合はsettings.pySTATICFILES_DIRSを定義します。

STATICFILES_DIRS = [  
    BASE_DIR / 'core/myfile',  
]  

↑の場合、BASE_DIR / 'core/myfile'という式でパスを合成しています。
その結果はリストの中に保存されます。
STATICFILES_DIRSが定義されている場合、Djangoはここに設定されているパスも静的ファイルの管理対象として見に行きます。
また、collectsatticコマンドもここに設定されたパスから静的ファイルを収集します。

collectstaticコマンドを実行する

実際にcollectstaticコマンドを実行してみたいと思います。
まず前提として、coreアプリというアプリを作成済みです。
coreアプリには↓のように静的ファイルが配置されています。

core  
├── myfile  
│         └── core  
│             └── img  
│                 └── yellow-ball.jpg  
└── static  
          └── core  
              └── img  
                  └── ball.jpg  

myfile/core/img/yellow-ball.jpgstatic/core/img/ball.jpgはどちらも画像ファイルです。
またsettings.pyには↓のように静的ファイルの設定が書かれています。

STATIC_URL = '/static/'  
STATIC_ROOT = '/var/sample.com/static/'  
STATICFILES_DIRS = [  
    BASE_DIR / 'core/myfile',  
]  

この状態のプロジェクトで以下のコマンドを実行します。

# python manage.py collectstatic  

134 static files copied to '/var/sample.com/static'.  

すると↑のように/var/sample.com/static/ディレクトリ以下に134の静的ファイルをコピーしたというメッセージが表示されます。
/var/sample.com/static/以下は↓のようになっています。

/var/sample.com/static# ls  
admin  core  

adminというディレクトリは管理サイト用の静的ファイルが集まっているディレクトリです。
coreというのは今回独自に作成したアプリの静的ファイルです。
coreの中身は↓のようになっています。

/var/sample.com/static/core# tree  
.  
└── img  
    ├── ball.jpg  
    └── yellow-ball.jpg  

1 directory, 2 files  

↑のようにstatic以下の画像とmyfile以下の画像が同じディレクトリに集まっています。
これはstatic以下とmyfile以下のディレクトリ構造がcore/imgとなっていて同じなためです。
このように同じディレクトリ構造では静的ファイルは一か所に収集されます。
同名のファイル名を使っている場合などに予期しないことになる可能性もあるので、アプリ内の静的ファイルはユニークな名前にしておきましょう。
また、staticディレクトリ以下のディレクトリ構造はstatic/アプリ名というディレクトリ構造にしておくと安心できます。
今回の場合はstatic/coreになっていますが、こうしておけば他のアプリとコリジョンすることがありません。

おわりに

今回はDjangoのcollectstaticコマンドを見てみました。
静的ファイルの管理はフレームワークを扱う場合の関心ごとの1つですが、Djangoでは非常にシンプルな解決方法を提供しているのがわかります。

🦝 < 静的ファイルを集めてデプロイ

🐭 < デプロイ!