【Django】静的ファイルの扱い方(画像・CSS・JS)

Djangoでの静的ファイルの扱い方の解説ページアイキャッチ

このページでは、Django での「静的ファイル(static ファイル)の扱い方」について解説していきます。

まず、Django で扱う静的ファイルには下記のようなものがあります。

  • 画像ファイル
  • CSS ファイル
  • JS(JavaScript)ファイル

静的ファイルとは、管理者や開発者がウェブアプリ動作用にあらかじめ用意しておくファイルで、ユーザーやリクエスト内容に関わらず毎回同じファイルを利用したいような場合に、この静的ファイルが使用されます。

例えば画像であれば、会社のロゴやアプリのロゴ・背景などには毎回同じ画像を利用しますので、これらは静的ファイルとして扱われることが多いです。

静的ファイルの場合、管理者や開発者が事前にファイルを用意しておくので、静的ファイルを扱うだけであればウェブアプリにファイルのアップロード機能は不要です。

それに対し、管理者や開発者ではなく「アプリのユーザー」がアップロードするファイルは静的ファイルではありません。こういったファイルを扱う場合、当然ユーザーがファイルをアップロードするのでウェブアプリにアップロード機能が必要ですし、アップロードされたファイルの保存処理や、保存されたファイルを管理するような処理も必要となります。

このページでは、そういったアップロードされるファイルについては扱わず、静的ファイルのみを扱っていきたいと思います。といっても、アップロードされたファイルであってもファイルを扱うという点では静的ファイルと同様の部分はあるので、その辺りは参考になると思います。

Django でのファイルの扱いはちょっとややこしいです。その理由は、開発時と本番環境とでファイルの扱い方が異なる点にあります。

このため、静的ファイルの扱い方をしっかり理解しておかないと、いざ本番環境に移行しようと思った際にファイルが上手く扱えなくってしまうことがあります。

本番環境に移行する際の具体的な手順は、機会があれば別途ページを作成て解説したいと思いますが、このページでも本番環境に移行する際に必要な設定等について簡単に解説させていただこうと思います。

静的ファイルを扱うために必要なこと

ウェブアプリでの静的ファイルの扱い方の手順を解説する前に、まずは Django で静的ファイルを扱うウェブアプリを開発するために必要なこと(やるべきこと)を整理しておきたいと思います。

これは、静的ファイルを扱う際の Django の動作について理解することで自然と洗い出すことができます。

といっても、静的ファイルを扱う際の動作は通常のウェブページでファイルを扱う際の動作と同様ですので、まずはウェブページでファイルを扱う際の流れを整理し、それを踏まえて静的ファイルを扱うウェブアプリを開発するために必要なことを整理していきたいと思います。

ウェブページでファイルが扱われる流れ

ということで、まずはウェブページでファイルが扱われる際の処理の流れ、特に画像ファイルを扱う際の処理の流れについて解説していきます。

皆さんも、ウェブページを見る際にはウェブブラウザのアドレスバーに URL を直接指定したり、リンクをクリックしたりすることでウェブページを閲覧すると思います。

これらを行うと、ウェブブラウザは指定された URL やクリックされたリンクの URL に応じたサーバーに対し、指定された ページの URL をリクエストすることになります。

このリクエストを受け取ったサーバーは、リクエストされた ページの URL に対応する HTML をレスポンスとして返却します。

そして、そのレスポンスを受け取ったウェブブラウザは HTML を解釈し、その解釈結果に基づいてページを描画することで、ウェブブラウザ上にウェブページが表示されることになります。

ページ表示時の処理の流れ

もし、その HTML 内にファイルを扱うタグが存在する場合、そのタグで指定される ファイルの URL を再度サーバーにリクエストします。

例えば、そのタグの1つが img タグになります。img タグは画像ファイルを表示するためのタグになります。

HTMLでの画像の表示

<img src="ファイルの URL">

表示する画像ファイルは、上記のように ファイルの URL として指定されます。表示を行うためには ファイルの URL の画像ファイルが必要になりますので、ウェブブラウザはこのファイルを取得するために再度サーバーに ファイルの URL をリクエストすることになります。

さらに、そのリクエストを受け取ったサーバーは、リクエストされた ファイルの URL に対応するファイルをレスポンスとして返却します。

そして、ウェブブラウザは受け取ったファイルを img タグ部分に画像として描画することで、ウェブページ上への画像の表示を実現しています。

画像ファイルを扱う際の処理の流れ

ウェブページで画像ファイルが扱われる際の処理の流れはこんな感じになります。

ここまで画像に絞って解説してきましたが、使用するタグ等は異なるものの CSS や JS(JavaScript)も同様で、要はファイルを扱うタグを含む HTML をウェブブラウザが受信すれば、そのタグで指定される ファイルの URL をサーバーにリクエストします。

そして、そのリクエストのレスポンスとして返却されたファイルをウェブブラウザが読み込み、例えば CSS であれば HTML の各要素の見た目を変更し、JS であればスクリプトを実行するという流れになるという違いがあるだけです。

スポンサーリンク

Django で静的ファイルを扱う流れ

Django で開発するウェブアプリでもウェブブラウザに画面を表示するために HTML を生成しますので、基本的にはファイルを扱う際の処理の流れは前述のウェブページとの時と同じです。したがって、上記のような流れを実現できるようにウェブアプリを開発する必要があります。

ただ、我々が Django を開発する際に主に変更を行う MTV(Model・Template・View)に限っていえば、ファイルを扱うために行うことはほとんどありません。

Django には「開発用ウェブサーバーソフト」が搭載されており、この開発用ウェブサーバーソフトが多くのことを処理してくれます(このウェブサーバーソフトは、前述のサーバー上で動作するソフトウェアになります。装置のサーバーと混同しないように “ソフト” と記しています)。

ちなみに、この開発用ウェブサーバーソフトは下記コマンドで起動します。

% python manage.py runserver

次は、この Django の開発用ウェブサーバーソフトと MTV の観点も含めて、ファイルを扱う際の処理の流れを確認していきましょう!

まず、ウェブブラウザから ページの URL がリクエストされた際には、Django の開発用ウェブサーバーソフトがリクエストを受け取り、そのリクエストされた ページの URL に応じて View の関数が実行されます。

ページの URL に対し、どの関数が実行されるかは urls.py によって関連付けられます。

そして、ここで実行された View は、Model や Template を利用して HTML を生成します。静的ファイルを扱う場合、この HTML に静的ファイルを扱うためのタグを含ませておく必要があります(具体的なタグについては後述します)。

この生成した HTML は Django の開発用ウェブサーバーソフトからウェブブラウザにレスポンスとして返却されます。

ページ表示時のDjangoの処理の流れ

さらに、HTML を受け取ったウェブブラウザは、ファイルを扱うためのタグで指定された ファイルの URL をサーバーにリクエストします。

そのリクエストを Django の開発用ウェブサーバーソフトが受け取り、リクエストされた ファイルの URL静的ファイルに対する URL である場合、その ファイルの URL に対応するファイルを「検索先フォルダ」から検索します。そして、そのファイルが存在する場合、そのファイルを取得してレスポンスとして返却します(存在しない場合は Not Found)。この時、MTV は動作しません。

MEMO

この「検索先フォルダ」という名前は、説明の便宜上私が名付けたものであって一般的な用語ではないので注意してください

こういった静的ファイルの検索先となるフォルダがあることは事実です

そして、ファイルを受け取ったウェブブラウザは、そのファイルを使用してウェブページを表示します。

静的ファイルを扱う際のDjangoの処理の流れ

静的ファイルを扱うウェブアプリ開発時に必要なこと

こんな感じで、静的ファイルを扱う点に限って考えれば、Django の開発用ウェブサーバーソフトがほとんど処理してくれるので難しいことはそんなにありません。

MTV に関して言えば、ファイルを扱わないウェブアプリ開発時に比較し、ファイルを扱うために必要なことは下記のみとなります。 

  • HTML にファイルを扱うタグを付ける

ただ、タグには属性で ファイルの URL を指定する必要があり、その ファイルの URL としては「静的ファイルへのリクエストであることが判別可能」であるものを指定する必要があります。この詳細については後述の 静的ファイルを扱う手順 で解説します。

また、静的ファイルへのリクエストを受け取った際に、Django の開発用ウェブサーバーソフトは「検索先フォルダ」からファイルを取得することになります(検索先フォルダがどこであるかは後述の 静的ファイルを扱う手順 で解説します)。

ですので、その検索先フォルダに事前にファイルを設置しておく必要があります。そして、前述の通り、静的ファイルの場合、このファイルは管理者やアプリ開発者が事前に設置しておく必要があります。

したがって、静的ファイルを扱うウェブアプリを開発する際には下記を行なっておく必要があります

  • 静的ファイルを設置する

また、Django の開発用ウェブサーバーソフトの静的ファイルの取得先である「検索先フォルダ」は特定のフォルダのみとなります。この検索先フォルダ以外のフォルダに静的ファイルを設置したい場合は、別途下記を行う必要があります。

  • 静的ファイルの検索先フォルダを増やす

まとめると、通常のウェブアプリに比べ、静的ファイルを扱うウェブアプリを開発する際には、下記の3つのことを行う必要があります。

  • HTML にファイルを扱うタグを付ける
  • 静的ファイルを設置する
  • 静的ファイルの検索先フォルダを追加する

静的ファイルを扱う手順

続いて、Django でウェブアプリを開発する際の静的ファイルを扱う手順について解説していきます。

前述の通り、通常のウェブアプリに比べ、静的ファイルを扱うウェブアプリを開発する際には下記の3つを行う必要があります(3つ目は必要に応じて実施)。

  • HTML にファイルを扱うタグを付ける
  • 静的ファイルを設置する
  • 静的ファイルの検索先フォルダを追加する

これらの1つ1つについて解説していきます。順番前後しますが、まずは「静的ファイルを設置する」から解説していきます。

スポンサーリンク

静的ファイルを設置する

まずは、静的ファイルを扱うためにウェブアプリで扱う静的ファイルを設置していきます。

静的ファイルを設置するフォルダ

結論としては、静的ファイルを設置する位置は プロジェクト名/アプリ名/static/アプリ名/ 以下となります。

静的ファイルの設置位置を示した図

ただし、プロジェクト名/アプリ名/static はデフォルトでは存在しませんので、手動で プロジェクト名/アプリ名/static 以下のフォルダを作成する必要があります。

MEMO

Windows の場合は、静的ファイルを設置するフォルダは プロジェクト名¥アプリ名¥static¥アプリ名¥ になると思います

Windows ユーザーの方は、ファイルパスに関しては、適宜 / を ¥ に置き換えて読み進めていただければ話が合うと思います(URL は / のままで良いはず)

プロジェクト名/アプリ名/static/アプリ名/ 以下に静的ファイルを設置する理由

Django で静的ファイルを扱う流れ で解説したように、Django の開発用ウェブサーバーソフトは、ファイルの URL へのリクエストが静的ファイルへのリクエストであると判断した際に、その ファイルの URL に対応するファイルを「検索先フォルダ」から取得します。

つまり、ウェブアプリで扱う静的ファイルは、その検索先フォルダ以下に設置しておく必要があります。

この「検索先フォルダ」には2種類あります。1つは管理者画面用の静的フォルダを設置するフォルダになります。が、今回はあくまでも我々が開発するウェブアプリでの静的ファイルの扱いについて解説を行なっていくため、こちらの管理者画面用の静的フォルダについてはこのページでは扱いません(図などでも省略させていただきます)。

もう1つは我々が開発するウェブアプリ用の検索先フォルダになります。こちらの検索フォルダがウェブアプリ開発において重要になります。

そして、アプリ用の検索先フォルダは プロジェクト名/アプリ名/static/ 以下となります。ですので、静的ファイルを扱うためには、プロジェクト名/アプリ名/static/ 以下に静的ファイルを設置しておく必要があります。

検索先フォルダの位置を示した図

上の図からも分かるように、アプリごとに検索先フォルダが用意されていることになりますので、アプリごとに分けて静的ファイルを設置するのが良いと思います。

ただ、プロジェクト名/アプリ名/static/ 以下に設置することで静的ファイルを扱うこと自体は可能なのですが、実際には プロジェクト名/アプリ名/static/ 以下ではなく、プロジェクト名/アプリ名/static/アプリ名/ に設置する方が良いです。

これは、使用する静的ファイルをアプリ毎に分けて管理できるようにするためです。

今後の解説を読んでいただければ分かると思いますが、ファイルの URL には検索先フォルダ以下のパスのみを指定することになります。ですので、検索先フォルダ直下にファイルを置いてしまうと、複数のアプリで同じ名前のファイルを利用しようとする場合、どのアプリ用のファイルであるかが ファイルの URL から判別できません。

そのため、どのアプリ用の静的ファイルであるかが判別できるよう、検索先フォルダの下に アプリ名 のフォルダを作成し、その中に静的ファイルを集めるようにしていきます。

プロジェクト名/アプリ名/static/アプリ名/ 以下のフォルダ構成は自由

また、プロジェクト名/アプリ名/static/アプリ名/ 以下のフォルダ構成は自由に決めて良いです。

例えば、扱う静的ファイルが多い場合、扱う静的ファイルの種類によってフォルダ分けをしたいような場合も出てくると思います。

その場合は、プロジェクト名/アプリ名/static/アプリ名 の下に別途フォルダを作成し、そのフォルダ内に静的ファイルを設置するようにしても問題ありません。

静的ファイルを設置する例

ここで、簡単に静的ファイルを設置する例を紹介していきたいと思います。

プロジェクト名が project で、このプロジェクト内に app1 というアプリと app2 というアプリが存在する場合の静的ファイルを設置する例を紹介していきます。

静的ファイル設置前のフォルダファイル構成

この構成において、app1image.pngstyle.css という静的ファイル、さらに app2pict.jpgscript.js という静的ファイルを扱えるよう、これらの静的ファイルを設置していきます。

 まず、前述の通り、静的ファイルは プロジェクト名/アプリ名/static/アプリ名/ 以下に設置します。

そのため、project/app1/static/app1/ 以下に image.pngstyle.css を、project/app2/static/app2/ 以下に pict.jpgscript.js を設置していくことになります。

ただ、project/app1/static 以下のフォルダと project/app2/static 以下のフォルダは存在しませんので、まずはこれらのフォルダを作成し、さらに作成したフォルダの中に app1app2 をそれぞれ作成する必要があります。

これらのフォルダが作成できれば、後は image.pngstyle.cssproject/app1/static/app1/ に、project/app2/static/app2/pict.jpgscript.js をそれぞれ設置すれば良いだけです。

プロジェクト名/アプリ名/static/アプリ名以下に静的ファイルを設置する様子

また、前述の通り、プロジェクト名/アプリ名/static/アプリ名/ 以下のフォルダ構成は自由です。

ですので、例えば project/app1/static/app1/ の下に img フォルダと css フォルダを作成し、前者のフォルダの中に image.png、後者のフォルダの中に style.css を設置するようにしても、問題なく設置した静的ファイルをアプリ app1 で使用することが可能です。

さらにフォルダ構成を分けて静的ファイルを設置する様子

HTML に静的ファイルを扱うタグを付ける

静的ファイルを設置した後は、その静的ファイルを扱う HTML を生成できるよう、View や Model、Template を作成していきます。といっても、ここで変更するのは Template のみになります。

静的ファイルを扱うために重要なのは、生成する HTML に静的ファイルを扱うためのタグを持たせることです。

さらに、静的ファイルを扱うためには、そのタグの src や href 属性に 静的ファイルを設置する で設置したファイルのパスに対応する URL を指定する必要があります。

静的ファイルを扱うタグ

まず、静的ファイルを扱うためのタグは下記となります(他にもあるかも)。静的ファイルを扱うために、これらのタグを持たせた HTML を作成していきます。

  • 画像:<img> タグ
  • CSS:<link> タグ
  • JS:<script> タグ

一応補足しておくと、これらのタグは静的ファイル用に限定されたものではなく、アップロードされたファイルを扱う際にも利用することができます。

扱う静的ファイルの指定

また、上記のタグの属性で ファイルの URL を指定することで、ウェブブラウザからサーバーに ファイルの URL がリクエストされるようになります。

この ファイルの URL を指定する属性はタグごとに異なるので注意してください。具体的には、それぞれ下記の属性によってリクエストする ファイルの URL を指定することになります。

  • <img> タグ:src="ファイルの URL"
  • <link> タグ:href="ファイルの URL"
  • <script> タグ:src="ファイルの URL"

他にも各タグで設定必要な属性はありますが、ここではその説明は省略させていただきます。

これらのタグを HTML 内に含ませておくことで、ファイルの URL に対応するファイルをウェブブラウザがリクエストして取得するようになり、例えば画像であれば <img> タグの場所に画像が表示されますし、CSS であれば HTML の各要素(見出しや段落などなど)の見た目の設定が行われます。さらに、JS であればスクリプトが実行されることになります。

静的ファイルであることを示す ファイルの URL の形式

で、ここで重要なのが、各属性に指定する ファイルの URL です。この ファイルの URL が、静的ファイルを設置する で設置したファイルに対応したものでないと、ファイルの URL の先にファイルが見つからず Not Found になってしまいます。

さらに、Django で静的ファイルを扱う流れ で解説したように、ファイルの URL は “静的ファイルであること” が判別可能である必要があります。

結論的には、ファイルの URL を次のような形式にすることで、上記を満たす URL を指定することが可能です。

指定するURLの形式

/STATIC_URL{検索先フォルダからのファイルの相対パス}

ちょっと分かりにくいので、1つ1つ説明していきます。

静的ファイルであることを示す STATIC_URL

前述の通り、静的ファイルを扱う場合、ファイルの URL は “静的ファイルであること” が判別可能なものでなければなりません。

上記の形式の URL において、”静的ファイルであること” を判別可能にするためのものが /STATIC_URL になります。ファイルの URL/STATIC_URL から始まる場合、Django の開発用ウェブサーバーソフトは URL が静的ファイルに対するものであると判断し、検索先フォルダから静的ファイルを取得してくれます。

逆に、ファイルの URL/STATIC_URL から始まらない場合は Django の開発用ウェブサーバーソフトでは静的ファイルとして扱われないので注意してください。

また、上記における STATIC_URL は、プロジェクト名/プロジェクト名/settings.py で定義される変数になります。

実際に プロジェクト名/プロジェクト名/settings.py のファイルを見てみれば分かると思いますが、おそらく下記のように STATIC_URL が定義されているのではないかと思います。

STATIC_URL

STATIC_URL = 'static/'

ですので、前述の ファイルのURL は下記のように書き換えることができます。ちょっと URL っぽくなりましたね(ルートパスで記述した URL)。

指定するURLの形式(STATIC_URL埋め込み)

/static/{検索先フォルダからのファイルの相対パス}

STATIC_URL は単に プロジェクト名/プロジェクト名/settings.py で定義されるものなので、ファイルの URL を指定するためには、後は {検索先フォルダからのファイルの相対パス} の部分をうまく指定してやれば良いことになります。

MEMO

古いバージョンの Django の場合、STATIC_URL = '/static/' と定義されている可能性があります

このように STATIC_URL が定義されている場合、以降の解説は、/STATIC_URL を STATIC_URL に置き換えて読んでいただければ話が合うはずです

{検索先フォルダからのファイルの相対パス}

で、静的ファイルを設置する で説明したように、静的ファイルの検索先フォルダは プロジェクト名/アプリ名/static/ となります。

ですので、{検索先フォルダからのファイルの相対パス} に関しては、静的ファイルを設置する で設置したファイルの プロジェクト名/アプリ名/static/ からの相対パスを指定すれば良いことになります。

例えば下図のようなフォルダ・ファイル構成において、image.png を読み込みたい場合について考えてみましょう。

検索フォルダからの相対パスを考える図

この場合、image.png は、プロジェクト名/アプリ名/static/ フォルダから見れば下記を辿った位置に存在することになります。

  • app1 フォルダ → img フォルダ → image.png

この辿ったフォルダを / で区切って表したものが、static フォルダからの相対パスとなります。つまり、app1/img/image.png ということですね!

ですので、ファイルの URL の後半の{検索先フォルダからのファイルの相対パス} には app1/img/image.png を指定することになります。

つまり、この image.png を読み込ませて表示したい場合は、img タグの src には下記を指定することになります。

image.pngのURL

/static/app1/img/image.png

直接 ファイルの URL を指定するデメリット

ここまでの流れの通りに考えれば、静的ファイルを扱う場合、Template で用意する .html ファイルに静的ファイルを扱うためのタグである <img><link><script> を用意し、src 属性や href 属性で前述の形式の URL をそのまま指定してやれば良いだけのように感じると思います。

例えば、先程の例で示した image.png の画像を表示するのであれば、下記の img タグを用意しておけばよさそうですよね!

image.png表示のためのimgタグ

<img src="/static/app1/img/image.png">

一応上記でも上手く画像を表示させる事は可能です。ですが、上記のように ファイルの URL を指定すると、ちょっと不便なことがあります。

前述の通り、ファイルの URL に指定する URL は下記の形式のものになります。

指定するURLの形式

/STATIC_URL{検索先フォルダからのファイルの相対パス}

/STATIC_URL は静的ファイルであることを示すものであり、さらに STATIC_URL は プロジェクト名/プロジェクト名/settings.py で定義された変数です。

つまり、プロジェクト名/プロジェクト名/settings.pySTATIC_URL が変更されると、ファイルの URL に指定すべき URL も変わってしまうのです。例えば STATIC_URL = 'static_files" みたいに変更されてしまうと、先頭が /static_files/ 以外の ファイルの URL のリクエストは静的ファイルへのリクエストとして扱われなくなり、検索先フォルダからファイルが取得されなくなってしまいます。

そのため、STATIC_URL の変更に合わせて ファイルの URL も変更する必要があります。例えば前述の img タグは次のように変更する必要があることになります。

STATIC_URLの変更に対応したimgタグ

<img src="/static_files/app1/img/image.png">

もちろん、HTML ファイル内に静的ファイルを読み込むタグが少ないのであれば問題ないですが、上記のようなタグがたくさん存在すると、全てのタグの ファイルの URL を変更する必要があるので大変です…。

正直、私も STATIC_URL を変更するケースがどんなものであるかは把握していないですが、STATIC_URL が変更される可能性があることを考えると、直接 ファイルの URL に /static/ と書くのではなく、STATIC_URL の値を読み込み、それを URL の前側に組み込むようにした方が安全です。

{% static %} テンプレートタグ

で、そのために用意されているのが {% static %} テンプレートタグになります。

Template の .html にこのテンプレートタグが記述されている場合、View からレンダリングされた際に(render 関数が実行された際に)、テンプレートタグ内の static の部分が /STATIC_URL に置き換えらます。

ただし、{% static %} テンプレートタグを利用するためには、事前に .html 内に {% load static %} を記述しておく必要があるので注意してください。{% load static %} を記述せずに {% static %} テンプレートタグを利用するとエラーになります。

例えば、前述の img タグを下記のように変更した場合、

テンプレートタグを利用したimgタグ

{% load static %}
<img src="{% static 'app1/img/image.png' %}">

レンダリング後には、static の部分が /STATIC_URL に置き換えられ、上記の img タグは次のように変化することになります(STATIC_URL = 'static/' の前提)。

レンダリング後のimgタグ

<img src="/static/app1/img/image.png">

もし、STATIC_URL = 'static_files/' のように STATIC_URL が変更されている場合でも、STATIC_URL の値に応じて ファイルの URL が生成されることになります。

STATIC_URL変更後のimgタグ

<img src="/static_files/app1/img/image.png">

こんな感じで、{% static %} テンプレートタグを利用することで、STATIC_URL に応じた ファイルの URL の指定が可能になります。

ですので、静的ファイルを扱う際には、Template の .html での ファイルの URL の指定は、下記のように {% static %} テンプレートタグを利用するのが良いです。

テンプレートタグを利用したファイルのURL

{% static '{検索先フォルダからのファイルの相対パス}' %}

前述の通り、{% static %} テンプレートタグを利用するためには事前に {% load static %} を記述しておく必要がある点に注意してください。Template の .html ファイルの先頭付近に記述しておくのが一般的だと思います。

静的ファイルの検索先フォルダを追加する

ここまでの解説内容を参考にしていただければ、静的ファイルを扱うウェブアプリを開発することができるはずです。後で実例も紹介しますので、それに関しては少々お待ちください。

ただ、ここまでの解説内容だけだと、静的ファイルを扱う上でまだ不十分な点があります。

静的ファイルを設置する で解説したように、静的ファイルの設置先は プロジェクト名/アプリ名/static/アプリ名/ 以下となります。これって要は、アプリごとに静的ファイルを設置するということになりますよね。

ただ、プロジェクト内に複数のアプリが存在する場合、アプリをまたがってプロジェクト内で共通して扱いたい静的ファイルもあるはずです。その場合はどのようにすれば良いでしょうか?

そのような静的ファイルを、とりあえず プロジェクト名/static/ 以下に設置したとしましょう。ただ、特定の設定を行わないと プロジェクト名/static/ に静的ファイルを設置しても、そのファイルをウェブアプリ内で扱うことはできません。

これは、静的ファイルへのリクエスト受けた際のファイルの取得先が「検索先フォルダ」のみとなっているからです。

そのため、プロジェクト名/static/ のように検索先フォルダとして設定されていないフォルダにどれだけ静的ファイルを設置したとしても、それらのファイルが静的ファイルへのリクエストに対するレスポンスとして返却されることはありません。

ただ、これは初期状態の Django の設定がそうなっているからであって、後述の手順を踏むことで任意のフォルダを検索先フォルダとして追加で設定することが可能です。

STATICFILES_DIRS で検索先フォルダを追加する

その検索先フォルダの追加の設定は、プロジェクト名/プロジェクト名/settings.py を変更することで行うことができます。

具体的には、下記の STATICFILES_DIRSプロジェクト名/プロジェクト名/settings.py に追記することで、検索先フォルダを追加することができます。追記するのは、STATIC_URL の定義の下側で良いと思います。

STATICFILES_DIRSの設定

STATICFILES_DIRS = (
    追加したいフォルダのパス
)

この STATICFILES_DIRS に指定したパスのフォルダも検索先フォルダとして扱われるようになるため、Django の開発用ウェブサーバーが静的ファイルへのリクエストを受けた際には、そのフォルダ以下も検索してくれるようになります。

そのため、そのフォルダ以下に設置した静的ファイルもレスポンスとして返却されるようになります(もちろん返却されるのは ファイルの URL に対応したファイルがフォルダ以下に存在する場合のみです)。

つまり、STATICFILES_DIRS に指定したフォルダ以下に設置したファイルもウェブアプリで静的ファイルとして扱うことができます。

STATICFILES_DIRSに追加したフォルダから静的ファイルを取得する様子

例えば、静的ファイルの検索先フォルダとして プロジェクト名/static/ を追加したいのであれば、プロジェクト名/プロジェクト名/settings.py に下記を追記します(BASE_DIRプロジェクト名/ のフォルダパスを指す変数です)。

STATICFILES_DIRSの設定の設定例

import os
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static/"),
)

これにより、/STATIC_URL{検索先フォルダからのファイルの相対パス} のリクエストを受けた時に プロジェクト名/static/{検索先フォルダからのファイルの相対パス} にファイルが存在するかどうかが確認されるようになり、存在すれば、そのファイルがレスポンスとして返却されるようになります。

もし存在しなければ、他の検索先フォルダが検索されることになります。

また、STATICFILES_DIRS には複数のフォルダを設定することも可能です。

スポンサーリンク

静的ファイルを扱うウェブアプリの例

続いて、ここまでの解説内容のまとめの意味も込めて、静的ファイルを扱う簡単な(超簡単な)ウェブアプリを作成していきたいと思います。

プロジェクトとアプリの作成

静的ファイルを扱うウェブアプリ開発時に必要なこと で解説したように、静的ファイルを扱うといっても下記以外に関しては通常のウェブアプリ開発時と手順は変わりません。

  • HTML にファイルを扱うタグを付ける
  • 静的ファイルを設置する
  • 静的ファイルの検索先フォルダを追加する

なので、まずはいつも通り Django を利用してウェブアプリを開発していきましょう!

今回はプロジェクト名を static_project、アプリ名を static_app として解説していきたいと思います。

まずは、startproject でプロジェクト static_project を作成します(コマンドの 部分は入力不要です。以降に関しても同様です)。

% django-admin startproject static_project

django-admin が実行できない場合は、下記ページが参考になると思います。

django-adminが実行できない場合の対処法の解説ページアイキャッチ【Python/Django】django-admin が実行できない場合の対処法(”コマンドが見つかりません”の対処法)

続いて、先程作成した static_project フォルダの中に移動し、startapp でアプリ static_app を作成します。

% python manage.py startapp static_app

次にプロジェクトにアプリ static_app を登録します。具体的には、static_project/static_project/settings.py を下記のように変更します。

アプリの登録

INSTALLED_APPS = [
    'static_app', # この行を追加
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

次は URL と関数のマッピングを行っていきます。まず、static_project/static_project/urls.py を下記のように変更します(includeimport が必要な点に注意)。

URLとアプリのマッピング

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('static_app/', include('static_app.urls'))
]

続いて、static_project/static_app/urls.py を新規作成し、ファイルの中に下記を追記します。

リクエストと関数のマッピング

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),
]

上記の変更により、http://127.0.0.1:8000/static_app/ へのリクエストを受け取った際に、static_project/static_app/views.py の index 関数が実行されるようになります。

静的ファイルの設置

次は 静的ファイルを設置する の解説内容に従って静的ファイルを設置していきましょう!

アプリの静的ファイルの設置

静的ファイルの設置場所は プロジェクト名/アプリ名/static/アプリ名 でしたね!

ただ、そのフォルダ以下にも任意のフォルダを作成することが可能ですので、今回は下記の4つのフォルダを作成し、後ろの2つのフォルダに静的ファイルを設置していきたいと思います(img に画像、css に CSS を設置していきます)。

  1. static_project/static_app/static
  2. static_project/static_app/static/static_app
  3. static_project/static_app/static/static_app/img
  4. static_project/static_app/static/static_app/css

続いて、上記のフォルダに設置するファイルを用意していきます。

画像はなんでも良いですが、今回は下の画像を使用することにしましょう!右クリックからファイルは保存できるはずです。ファイル名は image.png とし、上記の 3. のフォルダに保存しておいてください。

動作確認王に使用する静的画像ファイル1枚目

また、CSS もなんでも良いですが、今回は下記の CSS を使用することにしましょう!下記をコピペし、ファイル名を style.css として上記の 4. のフォルダに保存しておいてください。

style.css

.h2-red {
    color: #FF0000;
}

.h2-blue {
    color: #0000FF;
}

ここまでの解説通りに手順を踏んでいただければ、ファイルとフォルダは下の図のような構成になっているはずです。

現状のフォルダ構成を示す図

プロジェクトの静的ファイルの設置

今回は プロジェクト名/static の下にも静的ファイルを設置していこうと思います。

まずは、下記の2つのフォルダを作成してください。2. のフォルダに画像を設置していきます。

  1. static_project/static
  2. static_project/static/img

続いて、2. のフォルダに下の画像を保存して設置してください。このファイル名も image.png としておきましょう!

動作確認王に使用する静的画像ファイル2枚目

これで、ファイルやフォルダの構成は下の図のようになるはずです。

現状のフォルダ構成を示す図2

スポンサーリンク

Template の作成

続いて HTML の基になる Template を作成していきます。

今回は画像と CSS を静的ファイルとして扱いますので、HTML に静的ファイルを扱うタグを付ける で解説したように、<img> タグと <link> タグを含む HTML を作成していきます。さらに、これも HTML に静的ファイルを扱うタグを付ける で解説したように、これらのタグの src 属性と href 属性には下記の形式で ファイルの URL を指定していきます。

ファイルのURLの指定

{% static '{検索先フォルダからのファイルの相対パス}' %}

まずはいつも通り下記のフォルダを作成してください。

  1. static_project/static_app/templates
  2. static_project/static_app/templates/static_app

さらに、下記をコピペして index.html を作成し、2. のフォルダに格納します。

index.html

{% load static %}
<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="{% static 'static_app/css/style.css' %}">
    <title>画像の表示</title>
</head>
<body>
    <h1>画像の表示</h1>
    <div>
        <h2 class="h2-red">画像の表示結果1</h2>
        <img src="{% static 'static_app/img/image.png' %}">
        <h2 class="h2-blue">画像の表示結果2</h2>
        <img src="{% static 'img/image.png' %}">
    </div>
</body>
</html>

上記の HTML において、ポイントは3つあります。

1つ目は下記の ファイルの URL の指定形式に則って <link> タグの href 属性および <img> タグの src 属性を指定している点です。

ファイルのURLの指定

{% static '{ファイルの検索先フォルダからのファイル相対パス}' %}

また、ポイントの2つ目は、上記の static 以降の部分に、前述で作成した3つの静的ファイルのファイルパスを static フォルダからの相対パスで指定している点になります。

ポイントの3つ目は、{% static %} テンプレートタグを利用するために、index.html の先頭に {% load static %} を記述している点です。{% load static %} 記述する前に {% static %} テンプレートタグを利用すると例外が発生するので注意してください。

View の作成

次は View を作成していきます。

といっても、static_project/static_app/views.py を下記のように変更するだけです。

views.py

from django.shortcuts import render

def index(request):
    return render(request, 'static_app/index.html')

上記の render 関数の中で index.html から HTML が生成されることになります。

その際に、index.html{% static %} 部分に /STATIC_URL が組み込まれます。この STATIC_URLstatic_project/static_project/settings.py で定義される変数であり、デフォルトは 'static/' に設定されています。

ここまでの動作確認

とりあえずここまでの動作確認を行なってみましょう!

静的ファイルを扱うといっても、ウェブアプリはいつも通りの手順で動作させることができます。

まずは、static_project フォルダで下記コマンドを実行し、Django の開発用ウェブサーバーソフトを起動させます。

% python manage.py runserver

続いて、ウェブブラウザを開き、下記 URL にアクセスします。

http://127.0.0.1:8000/static_app/

すると、下の図のような画面が表示されると思います(文字のフォントはブラウザによって異なると思います)。

プロジェクト名/アプリ名/static/アプリ名の下に設置した静的ファイルが使用される様子

この表示結果におけるポイントは3つです。

まず1つ目のポイントが、画像の表示結果1画像の表示結果2 の見出しの色が変化している点です。これらの見出しには class を設定しており、静的ファイルの設置 で作成した style.cssの中での class の設定に応じて色が変化しています。

つまり、index.html の下記で指定した静的ファイル style.css の読み込みに成功しています。

style.cssの読み込み

<link rel="stylesheet" href="{% static 'static_app/css/style.css' %}">

読み込みに成功しているのは、上記タグが存在することによってウェブブラウザからサーバーにリクエストが送られる、そして、そのリクエストのレスポンスとして style.css を受け取る、という流れが実現できているからです。

2つ目のポイントが、画像の表示結果1 の下の画像が表示されている点です。この画像は、静的ファイルの設置 で作成した image.png になります。

つまり、index.html の下記で指定した静的ファイル image.png の読み込みに成功しています。

アプリフォルダの下のimage.pngの読み込み

<img src="{% static 'static_app/img/image.png' %}">

これらに対し、画像の表示結果2 の見出しの下の画像は表示されていません。つまり、index.html の下記で指定した静的ファイル image.png の読み込みに失敗しているということになります。これがポイントの3つ目です。

プロジェクトフォルダの下のimage.pngの読み込み

<img src="{% static 'img/image.png' %}">

なぜこのファイルだけ読み込みに失敗しているのでしょうか?

これは、img/image.png が検索先フォルダに存在しないからです。現状検索先フォルダは static_project/static_app/static/ のみであり、このフォルダ以下に img/image.png は存在しません。

ですので、上記のタグをきっかけにリクエストをサーバーにしたとしても、レスポンスが Not Found になってしまいます。

img/image.pngstatic_project/static/ に存在しますので、static_project/static/ を検索先フォルダに追加してやれば、2つ目の画像も表示することができるようになります。

スポンサーリンク

静的ファイルの検索先フォルダの追加

ということで、最後に index.html の下記で指定した静的ファイル image.png の読み込みできるよう、static_project/static/ を検索先フォルダに追加していきましょう!

プロジェクトフォルダの下のimage.pngの読み込み

<img src="{% static 'img/image.png' %}">

静的ファイルの検索先フォルダを追加する でも解説したように、この検索フォルダの追加は static_project/static_project/settings.py に下記を追記することで実現することができます(STATIC_URL の定義の後ろあたりに追加すれば良いです)。

検索先フォルダの追加

import os
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static/"),
)

上記追記後、再度先ほど同じ手順で Django の開発用ウェブサーバーソフトを起動させ、同じ URL にアクセスすれば、次は下の図のように2つの画像両方が表示されるようになることが確認できると思います。

設置した全ての静的ファイルが使用されてページが表示される様子

ちょっと回りくどい説明になってしまったかもしれませんが、この動作結果より、プロジェクト名/アプリ名/static/ 以下に設置した静的ファイルは設定不要で使用可能であり、他のフォルダに設置した静的ファイルを使用するためには、上記のように STATICFILES_DIRS の定義が必要になることを理解していただけたのではないかと思います。

本番環境での静的ファイルの扱い方

先程の動作確認からも分かるように、ウェブアプリで静的ファイルが扱えるようになりました!

お試しでウェブアプリを開発する際などは上記の解説内容のみを考慮して静的ファイルを扱えば十分です。

ただし、本番環境(開発したアプリをウェブに公開するような環境)で静的ファイルを扱う場合は、ここまでの解説内容に加え、もう少し手順が必要になります。

その理由について説明しておくと、まず本番環境で Django で開発したウェブアプリを動作させる場合、プロジェクト名/プロジェクト名/settings.pyDebug = False を設定する必要があります。

そして、Debug = False を設定した場合、静的ファイルのリクエストを受け取った場合でも、Django の開発用ウェブサーバーソフトは検索先フォルダからの静的ファイルの取得を行わなくなってしまいます。

つまり、Debug = False を設定すると静的ファイルのリクエストに対するレスポンスが毎回 Not Found になります。

ただ、これは本質的な問題ではありません。

なぜなら、本番環境においては Django の開発用ウェブサーバーソフトを使用しないからです。代わりに、Apache や Nginx などのウェブサーバーソフトが利用されます。

本番環境移行前後のウェブサーバーソフトの違い

なので、Django の開発用ウェブサーバーソフトが静的ファイルの検索を行わなくなったとしても実は関係ないのです。ただ、Debug = False を設定すると静的ファイルの検索が行われなくなることは覚えておくと良いと思います。

MEMO

実際には、上の図のように Apache や Nginx が直接 MTV とやりとりするのではなく、この2つの間にアプリケーションサーバーや Django フレームワークが存在します

が、静的ファイルを扱うことに限れば Apache や Nginx があれば解説できるので、これらは図や説明から省略させていただいています

ただし、Django の開発用ウェブサーバーソフトの代わりに Apache や Nginx などのウェブサーバーソフトを利用するようになるので、ウェブアプリを本番環境移行前と同様に動作させるためには、これらのウェブサーバーソフトに Django の開発用ウェブサーバーソフトと同様の動作をさせてあげる必要があります。

静的ファイルを扱う際にポイントになるのが、静的ファイルのリクエストに対する処理になると思います。

Django で静的ファイルを扱う流れ で解説したように、Django の開発用ウェブサーバーソフトは ファイルの URL のリクエストを受け取ると、その ファイルの URL が静的ファイルに対応するものである場合、検索先フォルダから静的ファイルを検索します。そして、ファイルが見つかれば、そのファイルをレスポンスとして返却します。

静的ファイルを扱う際のDjangoの処理の流れ

本番環境では、Django の開発用ウェブサーバーソフトの代わりに Apache や Nginix 等を利用することになるので、これらのウェブサーバーソフトに上記と同様の動作を行わせる必要があります。

ここでポイントになるのが2点です。

1点目は “静的ファイルに対するリクエストであるかどうか” を判別する際のルールです。

Django の開発用ウェブサーバーソフトが  ファイルの URL から静的ファイルに対するリクエストであるかどうかを判断するように、他のウェブサーバーソフトも ファイルの URL から静的ファイルに対するリクエストであるかどうかを判断できるようにする必要があります。

で、ここで重要なのが、Django の開発用ウェブサーバーソフトの時と「同じルール」で静的ファイルに対するリクエストであるかどうかを判断する必要があるという点になります。

HTML に静的ファイルを扱うタグを付ける で解説したように、Django の開発用ウェブサーバーソフトでは、ファイルの URL/STATIC_URL から始まる場合に静的ファイルに対するリクエストと判断します。

つまり、Apache や Ngindx 等のウェブサーバーソフトも ファイルの URL/STATIC_URL から始まる場合に “静的ファイルに対するリクエストである” と判断できるように、ウェブサーバーソフトの設定が必要になります。

2点目は検索先フォルダです。静的ファイルを設置する で解説したように、Django の開発用ウェブサーバーソフトの場合、各アプリにおける プロジェクト名/アプリ名/static/ が静的ファイルの検索先フォルダとなります。また、STATICFILES_DIRS を定義することで、検索先フォルダを追加することも可能です。

それに対し、Apache や Nginx の場合は、静的ファイルの検索先フォルダは1つにまとめておく必要があるようです。つまり、プロジェクト名/アプリ名/static/STATICFILES_DIRS で設定したフォルダに設置した静的ファイルを1つのフォルダ以下に集める必要があります。

静的ファイルを1つのフォルダ以下に集める様子

そして、静的ファイルに対するリクエストがあった際に、静的ファイルを集めたフォルダからファイルを取得するよう、ウェブサーバーソフトを設定する必要があります。

静的ファイルを集めたフォルダから静的ファイルを取得する様子

以上をまとめると、本番環境に移行する際には、静的ファイルのリクエストを本番環境前と同様に動作させるために、まずは「静的ファイルを1つのフォルダに集める」必要があります。これは、Django に用意された collectstatic を行うことで簡単に行うことができます。

さらに、ウェブサーバーソフトに下記の2つを設定する必要があります。

  • 静的ファイルの判別ルール
  • 静的ファイルの取得先フォルダ

この設定方法は、使用するウェブサーバーソフトによって異なります。そのため、このページでは詳細は説明しませんが、Nginx での設定方法を簡単にだけ説明しておきたいと思います。

静的ファイルを1つのフォルダに集める

ということで、まずは本番環境への移行を行う際に必要な「静的ファイルを1つのフォルダに集める」ための手順を解説しておきます。

今まで静的ファイルは プロジェクト名/アプリ名/static/アプリ名 以下や STATICFILES_DIRS で設定したフォルダ以下に設置してきました。

前述の通り、これらのファイルを本番環境に移行する際には1つのフォルダに集める必要があります。せっかく色んなフォルダに分けて静的ファイルを設置してきたのに、それが無駄になるような気もしてしまうかもしれませんが、そうではないので安心してください。

上記のようなフォルダに設置してきたおかげで、collectstatic を行うだけでファイルを一箇所にまとめることができ、さらに Template の変更も不要になります。

collectstatic とは

この collectstatic は、STATIC_ROOT で指定したフォルダ以下に静的ファイルを集めるコマンドになります。Django に用意されたコマンドであり、Django が使用できれば collectstatic も実行可能です。

具体的には、検索先フォルダとして設定されているフォルダ以下の静的ファイルが全て STATIC_ROOT で指定したフォルダ以下に集められます。

ただ、STATICFILES_DIRS で検索先フォルダを設定している場合は注意点があるので、それについては collectstatic の注意点 で解説します。

さらに、collectstatic では、検索先フォルダ以下のフォルダ・ファイル構造を保ったまま、STATIC_ROOT で定義したフォルダ以下に静的ファイルを集めることができます。

collectstaticで検索フォルダ以下のフォルダ構造を保ったまま静的ファイルが集められる様子

つまり、後述するウェブサーバーソフトの設定で STATIC_ROOT を検索先フォルダとして設定してやれば、collectstatic 実行後も集められたファイルの {ファイルの検索先フォルダからのファイルの相対パス} は変化しないことになります。

ということは、ここまで静的ファイルを扱うために下記の形式で ファイルの URL を指定していますので、collectstatic で静的ファイルを集めた後も、この ファイルの URL の後半部分は変更する必要がないことになります。

指定するURLの形式

/STATIC_URL{検索先フォルダからのファイルの相対パス}

また、collectstatic では、検索先フォルダ以下のフォルダやファイル構造を保ったまま STATIC_ROOT 以下に静的ファイルが集められることになりますので、プロジェクト名/アプリ名/static/アプリ名/ 以下のファイルは STATIC_ROOT/アプリ名/ 以下に集められることになります。

すなわち、アプリごとに管理されていた静的ファイルは、STATIC_ROOT 以下に集められた後もアプリごと管理されることになります。

もし プロジェクト名/アプリ名/static/ 直下にファイルを設置していた場合は、STATIC_ROOT 以下に全てのファイルが集められることになります。そのため、異なるアプリで同じファイル名の静的ファイルを使用していた場合、collectstatic を実行すると、それらのファイルの1つ以外は上書きされることになってしまいます。

これを防ぐために、静的ファイルを設置する で解説したように、検索先フォルダは プロジェクト名/アプリ名/static/ であるものの、その下に アプリ名 のフォルダを作成してその中に静的ファイルを設置するようにしてきたというわけです。

collectstatic の実行手順

では、この collectstatic の実行手順について解説していきます。

collectstatic を実行する前に、まずは プロジェクト名/プロジェクト名/settings.py に静的ファイルを集めるフォルダを STATIC_ROOT として定義します。定義場所は STATIC_URL の定義位置の下くらいで良いと思います。

STATIC_ROOTの定義に追加

STATIC_ROOT = 静的ファイルを集めたいフォルダ

続いて、プロジェクト名/ の中で下記コマンドを実行します。これにより collectstatic が実行され、STATIC_ROOT のフォルダ以下に静的ファイルが集められます(途中で上書きして良いかどうか聞かれた場合は yes を入力してエンターキーを押してください)。

% python manage.py collectstatic

例えば、静的ファイルを扱うウェブアプリの例 で作成したプロジェクトにおいて、static_project/static_app/settings.py に下記を追記し、

STATIC_ROOTの設定例

import os
STATIC_ROOT = os.path.join(BASE_DIR, "public_static/")

その後に下記コマンドを実行すれば、

% python manage.py collectstatic

下の図のような構成で static_project/public_static 以下に静的ファイルが集められることになります。

collectstatic後のフォルダとファイルの構成

ここまで説明を避けてきましたが、静的ファイルを設置する で少し触れたように、検索先フォルダには管理者画面用のものが存在します。その検索フォルダの中に設置されている静的ファイルも、上の図のように admin フォルダ以下に集められることになります。

collectstatic の注意点

さて、STATIC_ROOT 以下に静的ファイルを集める際に使用した collectstatic ですが、使用時に注意点があります。

それは、STATIC_ROOT に指定するフォルダと STATICFILES_DIRS に指定するフォルダが重複してはいけないという点になります。重複していると下記のようなエラーが発生します。

ERRORS:
?: (staticfiles.E002) The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting.

そのため、STATICFILES_DIRS に指定しているフォルダに静的ファイルを集めたい場合は、プロジェクト名/プロジェクト名/settings.py の設定に注意が必要になります。

このような場合、collectstatic を実行する前に、まずは STATICFILES_DIRS の設定から STATIC_ROOT に指定したいフォルダを取り除く必要があります。そして、STATIC_ROOT の方に取り除いたフォルダを指定します。

例えば下記のように STATICFILES_DIRS を定義しており、STATIC_ROOT にも同じフォルダの os.path.join(BASE_DIR, "static/") を指定したい場合は、

検索先フォルダの追加設定

import os
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static/"),
)

まず下記のように STATICFILES_DIRS から os.path.join(BASE_DIR, "static/") 部分をコメントアウトし、

検索先フォルダからの取り外し

import os
STATICFILES_DIRS = (
    #os.path.join(BASE_DIR, "static/"),
)

さらに STATIC_ROOT = os.path.join(BASE_DIR, "static/") の定義を追加します。

重複解消後のSTATIC_ROOTの定義

import os
STATICFILES_DIRS = (
    #os.path.join(BASE_DIR, "static/"),
)

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

このように設定を行うことで、STATIC_ROOT に指定するフォルダと STATICFILES_DIRS に指定するフォルダの重複が解消され、collectstatic によって STATIC_ROOT 以下に静的ファイルを集めることができることになります。

また、もともと STATICFILES_DIRS に指定していたフォルダの下に静的ファイルが集められることになりますので、STATICFILES_DIRS に指定していたフォルダ以下の静的ファイルも含めて一箇所に集められることになります。

上記のケース以外の場合、すなわち静的ファイルを集めたいフォルダを STATICFILES_DIRS に指定していない場合、また、そもそも STATICFILES_DIRS を定義していない場合は、何も気にせず STATIC_ROOT を定義し、collectstatic を実行してやれば良いだけです。

もし STATICFILES_DIRS を定義している場合は、その STATICFILES_DIRS で指定したフォルダ以下の静的ファイルも STATIC_ROOT のフォルダ以下に集められることになります。

スポンサーリンク

ウェブサーバーソフトの設定を行う

STATIC_ROOT 以下に静的ファイルを集めたので、次は静的ファイルに対するリクエスト時に STATIC_ROOT のフォルダから静的ファイルを取得するよう、ウェブサーバーソフトの設定を行うことになります。

また、ファイルの URL から静的ファイルに対するリクエストであることを判別できるようにウェブサーバーソフトの設定も行う必要もあります。

HTML に静的ファイルを扱うタグを付ける で解説したように、Django の開発用ウェブサーバーソフトでは、ファイルの URL/STATIC_URL から始まる場合に静的ファイルに対するリクエストと判断するようになっていますので、ウェブサーバーソフトも同様のルールで静的ファイルに対するリクエストと判断させるように設定する必要があります。そして、静的ファイルに対するリクエストと判断した際に、STATIC_ROOT のフォルダから静的ファイルを取得するように設定を行います。

例えば、ウェブサーバーソフトに Nginx を使用するのであれば、Nginx の設定ファイルに下記を追記することで上記の設定を実現することができます。

ただ、Nginx 等は Django の変数を解釈してくれないため、STATIC_URLプロジェクト名/プロジェクト名/settings.py での STATIC_URL の定義値、STATIC_ROOTプロジェクト名/プロジェクト名/settings.py での STATIC_ROOT の定義値に直接置き換えて記述する必要があります。

Nginxの設定例

server {
    〜略〜

    location /STATIC_URL {
        alias STATIC_ROOT;
    }

    〜略〜
}

上記は、ファイルの URL の先頭が location の後ろに記述したものと一致する場合、alias の後ろに記述したフォルダからファイルを取得することを指定する設定になります。

Nginxのlocationとaliasの設定に従って静的ファイルを取得する様子

ここまで解説してきたように、<img> タグや <link> タグ等で指定する ファイルの URL は下記の形式で指定していますので、このタグが含まれる HTML を受け取ったウェブブラウザは下記の形式の  ファイルの URL をサーバーにリクエストすることになります。

指定するURLの形式

/STATIC_URL{検索先フォルダからのファイルの相対パス}

そして、リクエストを受け取った Nginx は、上記の追記した設定に従って動作をしてレスポンスを返却します。

すなわち、リクエストされた ファイルの URL の先頭が /STATIC_URL と一致するので、STATIC_ROOT 以下のフォルダから {検索先フォルダからのファイルの相対パス} のファイルを取得し、それをレスポンスとして返却します。

つまり、検索先フォルダが異なるものの、Django の開発用ウェブサーバーソフト利用時と同様の動作をさせることができ、これによって本番環境においても Django で開発したウェブアプリで静的ファイルを扱うことができるようになります。

例えば、プロジェクト名/プロジェクト名/settings.pySTATIC_URL = 'static/'STATIC_ROOT = '/home/daeu/project/static/' と定義しているのであれば、Nginx の設定ファイルには下記を追記することになります。

Nginxの設定例

server {
    〜略〜

    location /static/ {
        alias /home/daeu/project/static/;
    }

    〜略〜
}

location で指定するパスの最後が / で終わる場合、alias で指定するパスの最後に / が必要になるので注意してください。

これにより、下記の ファイルの URL のリクエストを受け取った際には、/home/daeu/project/static/ 以下から {検索先フォルダからのファイルの相対パス} のファイルが取得されるようになります。

指定するURLの形式

/static/{検索先フォルダからのファイルの相対パス}

あくまでも今回は Nginx での設定例を上辺だけ解説させていただきましたが、本番環境に移行する際にどんな設定が必要であるかはイメージが湧いたのではないかと思います。

また、他のウェブサーバーソフトを利用する場合やアプリケーションサーバーを利用する場合も同様で、結局は静的ファイルへのリクエストであると判断するルールと静的ファイルの取得先のフォルダを設定すれば良いだけになるはずです。

また、機会があれば本番環境に移行する際の Django やウェブサーバーソフトの設定手順等も解説していきたいと思います。

まとめ

このページでは、Django での静的ファイルの扱い方について解説しました!

ひとまず、静的ファイルを扱うウェブアプリを開発する際には 静的ファイルを扱う手順 で解説した手順で静的ファイルを扱うようにすれば良いです。

そして、そのアプリを本番環境に移行してウェブで公開する際には、本番環境での静的ファイルの扱い方 を参考にして設定等を行えば良いです。ウェブサーバーによって設定方法は異なるとは思いますが、静的ファイルを集める際の手順はそのまま使えますし、ウェブサーバーに設定すべきこともすぐにイメージが湧くと思います。

また、静的ファイルを扱う手順 で解説した内容に基づいて静的ファイルを扱うようにしておくことにより、本番環境への移行もスムーズに行うことができます。

今回は、単に手順を説明するだけでなく、その手順が必要な理由も理解していただけるように解説をしたつもりです。また、 Django で静的ファイルが扱われる仕組みについても理解していただけるようにしたつもりです。

その分解説が長くなってしまいましたが、これらの理解がトラブル発生時等の原因解明に役立つと思いますので、静的ファイルの扱いが上手くいかなくて困ったような際には、是非このページに記載されている内容を確認してみてください!

同じカテゴリのページ一覧を表示

コメントを残す

メールアドレスが公開されることはありません。