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

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

このページにはプロモーションが含まれています

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

静的ファイルとは

最初に、「静的ファイル」とは何か?という点について解説していきます。

静的ファイル

まず、静的の逆の言葉である「動的」について簡単に説明します。

例えば Django で開発したウェブアプリによって表示されるページは、基本的には動的なページとなります。Django で開発したウェブアプリでは、基本的にはリクエストを受け取るたびにデータベースからレコードを取得してページを生成するようになっています。そのため、表示するタイミングによって異なるページが表示されることがあります。例えば、特定のテーブルの全てのレコードの一覧を表示するページであれば、レコードが追加されるたびに表示されるページが変化することになります。

ページが動的に生成される様子

MEMO

この Django 入門 の連載では、基本的にウェブサーバーを省略した図を示すようにしてきましたが、静的ファイルを扱う際にはウェブサーバーが重要となるため、このページの解説ではウェブサーバーも図に示すようにしていきます

また、ウェブサーバーとウェブアプリの間には AP サーバー等が存在する場合もありますが、このページの図では省略します

このように、動的なデータはリクエストされるたびに毎回新たに生成されることになります。ここまでの Django 入門 での解説では、主にビューがモデルやテンプレートファイルを利用してページを生成するための説明を行ってきましたが、これらは全て動的なページ表示を実現するためのものになります。

それに対し、静的ファイルとは「事前に用意されたファイルであり、そのまま配信されるだけのファイル」となります。事前に用意されたファイルがそのまま配信されるので、いつ・誰がファイルを取得しても、同じファイルが得られることになります。

静的ファイルの説明図

スポンサーリンク

静的ファイルとして扱う機会が多いファイル

ウェブアプリで扱う静的ファイルには下記のようなものがあります。

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

画像ファイルを扱うことで、ウェブアプリで表示するページ内に画像を表示することができるようになります。例えば、会社のロゴやアプリのロゴ・背景などには毎回同じ画像を利用しますので、これらは静的ファイルとして扱われることが多いです。

画像ファイルを利用したページの表示例

また、CSS ファイルを扱うことで、ページ内の各要素の見た目を設定することができるようになります。

CSSファイルを利用したページの表示例

さらに、JavaScript ファイルを扱うことで、ウェブアプリで表示するページ上で処理を実行したり、定期的にページに表示するデータを変化させるようなことが可能となります。

JSファイルをを利用したページの表示例

このように、静的ファイルを扱うことができるようになれば、ウェブアプリで実現できることの幅も広がります。特に、ここで紹介した画像ファイル・CSS ファイル・JavaScript ファイルに関しては利用する機会が多く、これらの扱い方の理解はウェブアプリを開発していく上で必須と言っても良いでしょう。ただ、ここまでの Django 入門 の連載の中では、動的なページの生成方法についてのみ解説を行ってきましたので、このページで静的ファイルの扱い方について解説していきたいと思います!

ここで、一点補足しておくと、先ほど「静的ファイルとして扱うことの多いファイル」として画像ファイルを挙げましたが、必ずしも「画像ファイル = 静的ファイル」というわけではないので、その点には注意してください。上記で挙げたのは静的ファイルとして扱うことの多いファイルであり、上記のファイルが必ず静的ファイルであるというわけではありません。

例えば、生成 AI を利用し、ユーザーからリクエストされた画像を生成して返却する場合、この画像は事前に用意したものではなく、ユーザーからリクエストされるたびに生成するものとなりますので、動的なデータということになります。

あくまでも、事前にファイルを用意しておき、リクエストされた時にそのまま配信されるだけのファイルが静的ファイルですので、この辺りの違いはしっかり理解しておきましょう!

静的ファイルの「利用」と「配信」

静的ファイルを扱うウェブアプリを開発するためには、大きく分けて2つのことを実現する必要があります。それが、「静的ファイルの利用」と「静的ファイルの配信」になります。

ここでは、「静的ファイルの利用」と「静的ファイルの配信」を実現するために、どういったことを実施していく必要があるのか?と言う点について説明していきます。これらを実現する具体的な手順については、次の章の 静的ファイルを扱う手順 で解説します。

静的ファイルの利用

先ほども説明したように、静的ファイルは、主にウェブブラウザ、すなわちクライアント側で利用されるファイルとなります。

静的ファイルの画像をページに表示するのもウェブブラウザですし、静的ファイルの CSS を読み込んでページの各要素の見た目を変更するのもウェブブラウザとなります。このように、静的ファイルを利用するのは主にウェブブラウザ、すなわちクライアント側となります。

ウェブブラウザが静的ファイルを利用する様子

ただし、ウェブブラウザは、受信した HTML に従って静的ファイルを利用することになります。なので、静的ファイルの利用の仕方は、HTML によって決まります。そして、この HTML は、ウェブアプリによって生成されることになりますので、この生成する HTML によって、ウェブアプリがウェブブラウザに対して「どの静的ファイル」を「どのようにして扱うのか」を指示することができることになります。

なので、この HTML の作成の仕方が、ウェブアプリでの「静的ファイルの利用」のポイントとなります。

ウェブブラウザが、ウェブアプリの生成したHTMLに従って静的ファイルを利用する様子

タグで静的ファイルの利用を指示する

で、「どの静的ファイルを」「どのように扱うのか」に関しては、HTML 内に記述されるタグによって決まります。

具体的には、扱う静的ファイルは「タグの属性で指定される URL」によって決まります。さらに、どのように扱うのかは「タグの種類(及び属性)」によって決まります。

例えば、下記は、/static/app/img/cat.png を画像として扱うことを指示するタグとなります。

静的ファイルを扱うことを指示するタグ
<img src="/static/app/img/cat.png">

ファイルを扱うタグについての詳細に関しては追って解説していきますが、まずは静的ファイルを扱うことを指示するタグを HTML に記述しておくことで、ウェブブラウザから静的ファイルが利用されるようになる点は覚えておいてください。

静的ファイルの取得

また、静的ファイルを利用するためには、まずは、その静的ファイルを取得する必要があります。

そのため、先ほど示したような「静的ファイルを扱うことを指示するタグ」が HTML に存在すると、ウェブブラウザが自動的にリクエストを送信して必要な静的ファイルを取得するようになっています。具体的には、メソッドが GET、URL が タグで指定された URL であるリクエストが送信され、そのレスポンスとして静的ファイルが取得されることになります。

静的ファイルの取得のリクエスト

例えば、クライアント側が何かしらのページを表示しようとしてリクエストを送信し、そのレスポンスとして下記のような HTML を受信したとしましょう。下記の色付きの背景で示す箇所は「静的ファイルを扱うことを指示するタグ」となります。

受信したHTML
<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="/static/forum/css/style.css">
    <script type="text/javascript" src="/static/forum/js/forum.js"></script>
    <title>コメント一覧</title>
</head>
<body>
    <main>
        <h1 class="title">コメント一覧</h1>
        <table>
            <tr><th>ID</th><th>投稿者</th><th>コメント</th></tr>
            <tr><td>1</td><td>山田花子</td><td>よろしくです</td></tr>
            <tr><td>2</td><td>山田太郎</td><td>こちらこそ!</td></tr>
        </table>
    </main>
    <footer>
        <div class="logo">
            <img class="mini" src="/static/forum/img/logo.png">
        </div>
    </footer>
</body>
</html>

例えば、下記の img タグは src の画像を表示することを指示するタグとなります。

画像の表示
<img class="mini" src="/static/forum/img/logo.png">

このような img タグを受信した HTML 内から見つけると、ウェブブラウザは、src 属性で指定される URL のデータの取得のリクエストを自動的に送信します。そして、そのレスポンスとして画像を取得することで、その画像をページに表示することができるようになります。

画像表示を伴うページの表示の流れ

同様に、下記のような rel="stylesheet" が指定されている link タグは「CSS の読み込み」を指示するタグであり、このタグが HTML 内に存在すれば、ウェブブラウザが自動的に href 属性で指定される URL のデータの取得のリクエストを送信し、取得した CSS に応じて見た目の設定が行われたページを表示してくれます。

CSSの読み込み
<link rel="stylesheet" href="/static/forum/css/style.css">

さらに、下記のような script タグは「JavaScript の読み込み」を指示するタグであり、このタグが HTML 内に存在すれば、ウェブブラウザが自動的に src 属性で指定される URL のデータの取得のリクエストを送信し、取得した JavaScript を実行してくれます。

JavaScriptの読み込み
<script type="text/javascript" src="/static/forum/js/forum.js">

したがって、先ほど示した HTML においては、HTML 自体を取得するために1回、さらに、各種静的ファイルを取得するために3回のリクエストが送信されることになります。そして、これら4回のリクエストで受信したファイル・データを利用してページの表示が行われることになります。

こんな感じで、ウェブブラウザは受信した HTML 内のタグに応じて自動的にリクエストを送信して静的ファイルを取得し、その取得した静的ファイルが適切に利用されるようになっています。

なので、ウェブアプリで静的ファイルを扱うようにするためには、まずは「静的ファイルの利用を指示するタグ」が含まれる HTML を生成するようにウェブアプリを開発することが必要となります。

Django でウェブアプリを開発する場合、この HTML はビューでモデルやテンプレートファイルを利用して生成されるデータとなりますので、ウェブアプリで静的ファイルを扱うためには、上記のような img タグ・link タグ・script タグ等の静的ファイルを利用するためのタグを含む HTML を生成できるように、ビュー・モデル・テンプレートファイル、すなわち MTV を開発する必要があります。特に、HTML の大枠はテンプレートファイルから生成されますので、テンプレートファイルを img タグ・link タグ・script タグが含まれるように作ってやれば良いことになります。

静的ファイルを扱うためにウェブアプリで実施する必要のあることを示す図

スポンサーリンク

静的ファイルの配信

ここまで説明してきたように、ウェブブラウザは、受信した HTML 内に静的ファイルを扱うことを指示するタグを見つけると、自動的にリクエストを送信して静的ファイルを取得するようになっています。

そして、このリクエストの送信先は、基本的には、最初のページ表示に対するリクエストの送信先と同じサーバーとなります。したがって、サーバー側は、リクエストされた静的ファイルをレスポンスとして返却できるように、すなわち、静的ファイルが配信できるように準備しておく必要があります。

で、この静的ファイルの配信は、サーバーの中のウェブサーバーによって実現することが一般的です。したがって、「静的ファイルに対するリクエスト」を受け取った時に、ウェブアプリを動作させることなく、事前に用意されたファイルを特定のフォルダから取得し、それをレスポンスとして返却するようにウェブサーバーの設定等を行っておく必要があります。

静的ファイルに対するリクエストを受け取った時にはウェブアプリを動作させないことを示す図

ただし、ウェブサーバーが、どんなリクエストでも「静的ファイルに対するリクエスト」であると判断してしまうと、今度はウェブアプリが動作しなくなってしまいます。したがって、「静的ファイルへのリクエストとみなす判断基準」を決め、それを満たすリクエストの場合に、ウェブアプリを動作させることなくファイルの返却のみを行うようにウェブサーバーの設定等を行う必要があります。

この判断基準は、基本的にはルートパス形式における「URL の先頭の文字列」であると考えて良いです。すなわち、「静的ファイルであることを示す URL のプレフィックス」をウェブサーバーに設定します。これにより、そのプレフィックスとリクエストの URL の先頭が一致する場合に、静的ファイルの配信が行われるようになります。

静的ファイルに対するリクエストであるとウェブサーバーが判断できるようにウェブサーバーの設定を行う必要がある

また、ウェブサーバーが「静的ファイルに対するリクエスト」を受け取った時の「静的ファイルの取得先」に関しても、事前に設定しておく必要があります。

つまり、静的ファイルの配信を実現するためには、ウェブサーバーに対して「静的ファイルであることを示す URL のプレフィックス」と「静的ファイルの取得先」の設定が必要となります。簡単に言えば、「こういうリクエストを受け取った時は、ここから静的ファイルを取得して配信してね」という設定がウェブサーバーに必要となります。

静的ファイルの配信のためのウェブサーバーの設定が必要であることを示す図

開発用ウェブサーバーでの静的ファイルの配信

また、Django でウェブアプリを開発する場合は、ウェブアプリの動作確認にはウェブサーバーとして「Django の開発用ウェブサーバー」を利用することになります。なので、まずは開発用ウェブサーバーでの静的ファイルの配信を実現する必要があります。

開発用ウェブサーバーにおける静的ファイルの配信

ただ、開発用ウェブサーバーでの静的ファイルの配信の実現は非常に簡単です。なぜなら、開発用ウェブサーバーは、デフォルトで「静的ファイルであることを示す URL のプレフィックス」と「静的ファイルの取得先」が設定済みだからです。

なので、その「静的ファイルの取得先」にファイルを設置さえしておけば、「静的ファイルであることを示す URL のプレフィックス」から始まる URL のリクエストを受け取ったタイミングで、自動的に静的ファイルが開発用ウェブサーバーから配信されるようになります。したがって、開発用ウェブサーバーで静的ファイルの配信を実現するために最低限必要となる作業は、「静的ファイルの取得先」への静的ファイルの設置のみということになります。

開発用ウェブサーバーでの静的ファイルの配信を実現するために最低限必要となる作業を示す図

ただし、静的ファイルの利用の観点で言うと、「静的ファイルであることを示す URL のプレフィックス」から始まる URL のリクエストが送信されるような HTML の生成(タグの記述)も必要となります。この辺りの具体的な手順に関しては、後述の 静的ファイルを扱う手順 で解説します。

また、これらの開発用ウェブサーバーにおける「静的ファイルであることを示す URL のプレフィックス」と「静的ファイルの取得先」は変更可能なので、この変更方法についても 静的ファイルを扱う手順 で解説していきます。

本番環境での静的ファイルの配信

ただ、開発用ウェブサーバーは、あくまでもウェブアプリ開発時の動作確認に利用するものであって、本番環境(ウェブアプリを公開する環境)では利用しません。本番環境では、Apache や Nginx といった一般的なウェブサーバーを利用することになります(以降では、これらの本番環境で利用するウェブサーバーのことを公開用ウェブサーバーと呼ばせていただきます)。

開発環境と本番環境の違いを示す図

なので、本番環境に移行するためには、開発用ウェブサーバーとは別に、これらの公開用ウェブサーバーで静的ファイルが配信できるように公開用ウェブサーバーの設定も必要となります。

ですが、本番環境においても、基本的に設定すべきことは「静的ファイルであることを示す URL のプレフィックス」と「静的ファイルの取得先」となります。これらの設定を行ったうえで、「静的ファイルの取得先」に配信する静的ファイルを配置することで、静的ファイルの配信が実現できることになります。

「静的ファイルであることを示す URL のプレフィックス」に関しては、開発用ウェブサーバーと公開用ウェブサーバーとで同じものを設定するようにすれば、開発環境から本番環境への移行がスムーズになります。

本番環境への移行をスムーズにするために、開発用ウェブサーバーと公開用ウェブサーバーとで、「静的ファイルであることを示すURLのプレフィックス」を同一にすることが必要であることを示す図

ただ、「静的ファイルの取得先」に関しては、開発用ウェブサーバーと公開用ウェブサーバーとで同じにするのは難しいです。詳細は後述で解説しますが、開発を容易にするため、開発用ウェブサーバーの「静的ファイルの取得先」は複数のフォルダに分かれています。それに対し、公開用ウェブサーバーであ「静的ファイルの取得先」は1つのフォルダのみとするのが一般的です。これは、静的ファイルの取得のリクエストに対するレスポンス速度を向上させるためです。また、そもそも開発環境と本番環境とで OS が異なり、フォルダ構成も異なる可能性があります。

なので、「静的ファイルの取得先」は、開発環境と本番環境とで基本的には異なることになります。ただし、開発環境から本番環境への移行をスムーズに実施するためのコマンドが Django には用意されています。このコマンドを利用すれば、開発用ウェブサーバーにおける「静的ファイルの取得先」のフォルダ以下に設置された静的ファイルをコピーして一か所に集約ことが可能です。

開発環境で配信する静的ファイルを一箇所に集約する様子

なので、この集約先を公開ウェブサーバーにおける「静的ファイルの取得先」に設定してやれば、本番環境用に手動で静的ファイルを設置する手間を省くことができます。このあたりの具体的な手順については、次の 静的ファイルを扱う手順 で解説していきます。

静的ファイルの利用と配信の実現

ここで、この章で解説してきた内容について簡単にまとめておきます。

まず、静的ファイルの利用を実現するためには、テンプレートファイルに「静的ファイルを利用することを指示するタグ」を記述することが必要となります。また、このタグに指定する URL は、ウェブサーバーに設定された「静的ファイルであることを示す URL のプレフィックス」から始まるものである必要があります。

また、開発用ウェブサーバーでの静的ファイルの配信は、「静的ファイルの取得先」であるフォルダに静的ファイルを設置することで実現できます。ただし「静的ファイルの取得先」の追加や「静的ファイルであることを示す URL のプレフィックス」の変更によって、静的ファイルの配信の仕方のカスタマイズを行うことも可能です。

さらに、最終的にウェブアプリを公開する際には、公開用ウェブサーバーでの静的ファイルの配信で実現するためのウェブサーバーの設定も必要となります。

静的ファイルを扱う手順

ウェブアプリで静的ファイルを扱うために必要となる手順のイメージが湧いてきたでしょうか?

次は、「静的ファイルの配信」と「静的ファイルの利用」を実現する具体的手順を説明していきます。

スポンサーリンク

静的ファイルを配信する手順(開発用ウェブサーバー)

まずは、開発用ウェブサーバーでの、静的ファイルを配信する手順について解説していきます。

静的ファイルの設置場所

前述の通り、開発用ウェブサーバーは、静的ファイルの取得のリクエストを受け取った時に、デフォルトで設定されている「静的ファイルの取得先」から静的ファイルを取得してクライアントにレスポンスとして返却するようになっています。なので、この「静的ファイルの取得先」に静的ファイルを設置しておけば、後はクライアントからのリクエストに応じて開発用ウェブサーバーが静的ファイルを配信してくれることになります。

開発用ウェブサーバーが静的ファイルの取得先となるフォルダから静的ファイルを取得する様子

この「静的ファイルの取得先」とは、具体的には下記のパスのフォルダとなります。パスの区切りを  /としていますので、Windows ユーザーの方はパスの区切りを \ に置き換えて解釈してください。このフォルダは startapp 等のコマンドでは自動生成されないので、手動で作成する必要があります。また、下記のフォルダより下の階層のフォルダ・ファイル構成は自由に決めて良いです。

プロジェクト名/アプリ名/static/

このパスからも分かるように、「静的ファイルの取得先」はアプリ毎に存在します。なので、静的ファイルは基本的にはアプリ毎に用意して上記フォルダに設置することになります。

開発用ウェブサーバーにおける静的ファイルの取得先の説明図

ということで、静的ファイルを用意し、さらに「静的ファイルの取得先」である上記のフォルダに静的ファイルを設置すれば、とりあえず開発用ウェブサーバーでの静的ファイルの配信自体は実現できることになります。

static フォルダ内には アプリ名 フォルダが必要

ただ、ウェブアプリで上手く静的ファイルを扱えるようにするためには、単に「静的ファイルの取得先」の直下に設置していくのではなく、下記のように「静的ファイルの取得先」である static フォルダの下に アプリ名 フォルダを作成し、その アプリ名 フォルダの中に静的ファイルを設置していく必要があります。

プロジェクト名/アプリ名/static/アプリ名

この理由は、static フォルダの直下に静的ファイルを設置すると、異なるアプリ間で同じ名前の静的ファイルが利用できなくなるからになります。

この詳細に関しては 静的ファイルを利用する手順 で説明しますので、まずは、アプリ毎に用意する静的ファイルは、static フォルダの直下に配置するのではなく、static フォルダの下に アプリ名 フォルダを用意し、そのフォルダ以下に設置していく必要があることを覚えておいてください。

STATICFILES_DIRS を定義する(必要に応じて)

開発用ウェブサーバーのデフォルトの「静的ファイルの取得先」は、先ほども示した下記のフォルダのみとなります。ただし、設定の変更により、他のフォルダを「静的ファイルの取得先」として追加することが可能です。

プロジェクト名/アプリ名/static/

これにより、静的ファイルの取得のリクエストを受け取った時に、開発用ウェブサーバーが、その追加したフォルダ内の静的ファイルも配信してくれるようになります。

静的ファイルの取得先を追加する様子

この「静的ファイルの取得先」の追加は、プロジェクトの settings.py に STATICFILES_DIRS を定義することで実施することができます。STATICFILES_DIRS には、「静的ファイルの取得先」として追加するフォルダのパスを要素とするリスト(タプル)を指定します。

静的ファイルの取得先の追加
STATICFILES_DIRS = [
    'フォルダのパス1',
    'フォルダのパス2',
    ...
]

この STATICFILES_DIRS の定義による「静的ファイルの取得先」の追加は、プロジェクト内で共通に扱いたい静的ファイルが存在する場合に実施することが多いです。

前述の通り、開発用ウェブサーバーでは、デフォルトで「静的ファイルの取得先」として下記のフォルダが設定されており、アプリ毎に静的ファイルを設置することができるようになっています。

プロジェクト名/アプリ名/static/

ただし、アプリ毎ではなく、プロジェクト内のアプリ全てで共通に扱うような静的ファイルの設置場所としては、上記のパスは不適切です。なので、プロジェクト全体で共通に扱うような静的ファイルの設置場所を追加したいような場合は、上記のとおり、STATICFILES_DIRSsettings.py に定義してやる必要があります。

例えば、下記のフォルダに静的ファイルを設置するようにしたいのであれば、

プロジェクト名/static/

下記のように STATICFILES_DIRSsettings.py に定義してやれば良いことになります。

プロジェクト内共通の静的ファイル置き場の追加
import os
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static/'),
]

この STATICFILES_DIRS の定義は必須ではありません。静的ファイルの設置場所を増やしたい場合のみ定義すればよいです。この定義が必要になるのは、前述の例でも示したように、プロジェクト内で共通に扱いたい静的ファイルが存在する場合になると思います。

以上の解説に基づいて、静的ファイルの設置、及び STATICFILES_DIRS の定義を行えば、開発用ウェブサーバーが静的ファイルの取得のリクエストを受け取った時に、クライアントに対して静的ファイルを配信してくれるようになります。

STATIC_URL の定義を変更する(必要に応じて)

ここまでの解説内容によって、静的ファイルの配信自体は実現できたことになります。静的ファイルに対するリクエストを受け取ると、開発用ウェブサーバーが、その静的ファイルを返却してくれます。

ですが、この「静的ファイルに対するリクエスト」とは、具体的に、どんなリクエストのことになるのでしょうか?

開発用ウェブサーバー自体は静的ファイルを配信する準備が整っていたとしても、これが分からないとリクエストの送信しようがないですね…。

ということで、この点について解説していくと、デフォルト設定の場合、開発用ウェブサーバーは、URL (ルートパス形式での URL) の先頭が /static/ であるリクエストを、静的ファイルに対するリクエストと判断するようになっています。つまり、開発用ウェブサーバーにデフォルトで設定された「静的ファイルであることを示す URL のプレフィックス」は /static/ となります。

そして、このような /static/ から始まる URL のリクエストを受け取ったときには、開発用ウェブサーバーが、URL の「/static/ よりも後ろ側のパス」に応じたファイルを取得してクライアントにレスポンスとして返却することになります。この取得するファイルについては、次の 静的ファイルを利用する手順 で詳細を解説します。

開発用ウェブサーバーがデフォルトで、/static/から始まるURLのリクエストを静的ファイルに対するリクエストとみなすことを説明する図

ただし、これはデフォルト設定での話であって、「静的ファイルであることを示す URL のプレフィックス」は /static/ から変更可能です。

この「静的ファイルであることを示す URL のプレフィックス」は、settings.pySTATIC_URL で定義されています。デフォルトでは、settings.pySTATIC_URL は下記のように定義されており、これの先頭に '/' を結合した文字列から始まる URL に対するリクエストを静的ファイルに対するリクエストと判断するようになっています。

STATIC_URLの定義
STATIC_URL = 'static/'

したがって、この STATIC_URL の値を変更すれば、開発用ウェブサーバーに、異なる文字列から始まる URL のリクエストを静的ファイルに対するリクエストと判断させることができるようになります。

例えば、下記のように STATIC_URL を定義すれば、開発用ウェブサーバーが /static_files/ から始まる URL を静的ファイルに対するリクエストと判断し、このようなリクエストを受け取った時に、静的ファイルの配信を行うようになります。

STATIC_URLの定義例
STATIC_URL = 'static_files/'

このように、STATIC_URL の変更は可能なのですが、基本的には STATIC_URL は変更せずにデフォルト値のまま使用するので良いと思います。ただし、既に本番環境でウェブサーバーが /static/ 以外の文字列から始まる URL を静的ファイルに対するリクエストと判断するようになっている場合は、本番環境のウェブサーバーに合わせて STATIC_URL を変更した方が、本番環境への移行がスムーズになります。

また、この STATIC_URL は、「静的ファイルであることを示す URL のプレフィックス」としての役割だけでなく、もう1つ別の役割も持っています。それについては、次の静的ファイルを利用する手順の解説の中で説明していきす。

静的ファイルを利用する手順

続いて、ウェブサーバーから配信される静的ファイルを利用するための手順について解説していきます。

静的ファイルの利用を指示するタグを記述する

静的ファイルの利用 で解説したように、HTML 内に静的ファイルの利用を指示するタグを見つけると、ウェブブラウザは自動的に静的ファイルを取得し、それをタグ種に応じて利用するようになっています。そのため、ウェブアプリで静的ファイルが利用されるようにするためには、ウェブアプリがレスポンスとして返却する HTML 内に「静的ファイルの利用を指示するタグ」を記述しておく必要があります。

Django で開発するウェブアプリでは、HTML はテンプレートファイルに従って生成されるようになっているため、基本的にはテンプレートファイルに「静的ファイルを扱うことを指示するタグ」を記述していくことになります。

また、静的ファイルを扱うことを指示するタグの代表例は下記となります。静的ファイルの扱い方に応じてタグ種を選択し、利用したい静的ファイルに応じてタグに URL を指定する必要があります。

タグ名 ファイル種 URLの指定 備考
img  画像 src 属性  
link  CSS href 属性 rel="stylesheet" を指定
script  JS src 属性  

URL は static テンプレートタグを利用して指定する

このタグの記述を行う上でポイントになるのが、URL の指定の仕方になります。この URL は static テンプレートタグを利用して指定する必要があります(ただし、static テンプレートタグを利用してはいけないケースもあるので、その点については後述で補足します)。

staticを利用したURLの指定
"{% static 'ファイルのパス' %}"

{% load static %} の記述も必要

この static テンプレートタグを利用するテンプレートファイルでは、事前に {% load static %} を記述しておく必要がある点に注意してください(ファイルの先頭に記述することが多いです)。{% load static %} を記述していないテンプレートファイルで static テンプレートタグを利用すると、下記の例外が発生することになります。

django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 8: 'static'. Did you forget to register or load this tag?

static テンプレートタグの役割

この static テンプレートタグの役割は、引数で与えられた 'ファイルのパス'静的ファイルに対するリクエストであることを示す URL に変換することになります。より具体的には、static テンプレートタグは、settings.py で定義される STATIC_URL で指定された文字列を 'ファイルのパス' の前側に結合するテンプレートタグとなります(STATIC_URL で指定された文字列の先頭が /でない場合は、先頭に / も結合する)。

staticテンプレートタグの効果の説明図

STATIC_URL の定義を変更する(必要に応じて) で説明したように、開発用ウェブサーバーでは、URL が STATIC_URL から始まる URL を(or '/' + STATIC_URL から始まる URL を)、静的ファイルに対するリクエストと判断するようになっています。したがって、static テンプレートタグによって変換された URL のリクエストは、自然と静的ファイルに対するリクエストであると判断されることになります。そして、その URL に対するリクエストの送信により、その変換元の 'ファイルのパス' で指定されたファイルをレスポンスとして得ることができることになります。

また、これも STATIC_URL の定義を変更する(必要に応じて) で説明したように、STATIC_URL のデフォルト値は 'static/' となっています。したがって、STATIC_URL を変更していない場合、下記のタグは、

staticを利用したURLの指定の例
<img src="{% static 'app/img/cat.png' %}">

static テンプレートタグの効果によって、下記のように変換されることになります。

変換後のタグ
<img src="/static/app/img/cat.png">

static テンプレートタグの引数

また、static テンプレートタグの引数となる 'ファイルのパス' には、そのタグで扱うことを指示したい静的ファイルの「静的ファイルの取得先」からの相対パスを指定します。パスの区切りは Windows を使用している場合も / としてオーケーです。

staticテンプレートタグの引数に指定するパスの説明図

例えば、project という名前のプロジェクトに app1 というアプリが存在する場合、project/app1/static が「静的ファイルの取得先」の1つとなります。そのため、下記のパスの静的ファイルを画像として表示したいのであれば、

project/app1/static/app1/img/cat.png

下記のような img タグをテンプレートファイルに記述しておく必要があります。app1/img/cat.png は、cat.png の project/app1/static からの相対パスとなります。

staticを利用したURLの指定の例
<img src="{% static 'app1/img/cat.png' %}">

で、このタグは、STATIC_URL がデフォルト設定の場合、static テンプレートタグの効果によって下記のように変換されることになります。

変換後のタグ
<img src="/static/app1/img/cat.png">

また、static フォルダ内には アプリ名 フォルダが必要 で説明した通り、静的ファイルを下記の「静的ファイルの取得先」のフォルダの直下に設置するのではなく、static フォルダ内に アプリ名 フォルダを作成し、その アプリ名 フォルダの中に静的ファイルを設置することが必要であると説明したのは、この 'ファイルのパス' に「静的ファイルの取得先」からの相対パスを指定する必要があり、この場合、異なるファイルであっても相対パスが同じになってしまう可能性があるからになります。

プロジェクト名/アプリ名/static/

例えば、下記のような2つの静的ファイルが存在する場合について考えてみましょう。

project/app1/static/img/cat.png
project/app2/static/img/cat.png

これらの2つの静的ファイルにおいて、「静的ファイルの取得先」からの相対パスは、下記のように全く同じものになってしまいます。なので、これらのファイルは区別して扱うことができなくなってしまいます。

img/cat.png
img/cat.png

それに対し、下記のように static フォルダの下に アプリ名 フォルダを作成し、その中に静的ファイルを設置するようにすれば、

project/app1/static/img/app1/cat.png
project/app2/static/img/app2/cat.png

下記のように、同じ名前のファイルであっても、相対パスは異なることになり、これらのファイルを区別して扱うことが可能となります。

img/app1/cat.png
img/app2/cat.png

このように、異なるアプリ間で同じ名前の静的ファイルを利用すると、それらのファイルが区別して扱うことができなくなるため、デフォルトで開発用ウェブサーバーに設定されている「静的ファイルの取得先」に直接ファイルを設置するのではなく、static フォルダの下に アプリ名 フォルダを作成し、その中に静的ファイルを設置する必要があります。

URL に応じた静的ファイルの取得

また、STATIC_URL (or '/' + STATIC_URL) から始まる URL のリクエストを受け取った際には、開発用ウェブサーバーは STATIC_URL の部分('/' + STATIC_URL の部分)を「静的ファイルの取得先のパス」に置換したパスのファイルの存在の有無の確認を実施することになります。

存在する場合は、そのファイルをレスポンスとして開発用ウェブサーバーがクライアントに返却することになります。「静的ファイルの取得先」は複数存在するため、順番に置換後のパスのファイルの有無を確認し、発見次第、そのファイルをレスポンスとして返却し、1つも見つからなかった場合は 404 エラーを返却することになります。

URLの/static/を静的ファイルの取得先のパスに変換したパスから静的ファイルを取得する様子

例えば、下記の3つが「静的ファイルの取得先」として設定されており、

  1. test_project/app1/static/
  2. test_project/app2/static/
  3. test_project/static/

さらに、下記の URL のリクエストを受け取ったとすると、

/static/app1/img/cat.png

開発用ウェブサーバーは下記の3つのパスにファイルが存在するかどうかを確認することになります。

  1. test_project/app1/static/app1/img/cat.png
  2. test_project/app2/static/app1/img/cat.png
  3. test_project/static/app1/img/cat.png

そして、ファイルが存在する場合は、最初に見つけたファイルがレスポンスとしてクライアントに返却され、クライアント側がファイルを取得することができることになります。

このような仕組みで静的ファイルの取得が行われるため、タグに指定する URL は、まず静的ファイルに対するリクエストであると判断されるように static テンプレートタグを利用して指定するようにし、さらに static テンプレートタグの引数には、扱うことを指示したい静的ファイルのパスを、「静的ファイルの取得先」からの相対パスで指定する必要があります。

staticテンプレートタグの引数等の説明図

static テンプレートタグを利用するメリット

もちろん、static テンプレートタグを利用せずに、タグに直接 URL を指定することも可能です。ですが、この場合、STATIC_URL に応じて開発用ウェブサーバーが静的ファイルに対するリクエストと判断する URL も変化するわけですから、STATIC_URL を変更するたびに、テンプレートファイルの変更も必要となります。このテンプレートファイルの変更を怠ると、テンプレートファイルのタグによって送信されるリクエストが「静的ファイルに対するリクエスト」と判断されなくなってしまいます。

staticテンプレートタグを利用しないデメリット

ですが、static テンプレートタグを利用して URL を指定している場合、STATIC_URL の値に応じて static テンプレートタグによる URL の変換結果も自動的に変化することになりますので、STATIC_URL 変更時のテンプレートファイルの変更は不要です。

staticテンプレートタグを利用するメリット

つまり、テンプレートファイルで static テンプレートタグを利用してタグに URL を指定している場合、そのタグの URL は、STATIC_URL を変更したとしても、常に開発用ウェブサーバーに設定された「静的ファイルであることを示す URL のプレフィックス」から始まる URL となります。なので、そのタグによって送信されるリクエストは、必ず静的ファイルに対するリクエストと判断されることになります。

staticテンプレートファイルを利用するメリットを説明する図

このように、static テンプレートタグを利用してタグの URL を指定することで、STATIC_URL 変更時のテンプレートファイルの変更の手間を省くことができますし、開発用ウェブサーバーの「静的ファイルであることを示す URL のプレフィックス」と、HTML のタグの URL のプレフィックスとが常に一致することになり、ウェブアプリと開発用ウェブサーバーとで常に話があった状態を保つことができるというメリットも得られます。

ということで、静的ファイルを扱うことを指示するタグを記述する場合は、static テンプレートタグを利用して URL を指定するようにしましょう。

外部サイトからの静的ファイルの取得

ただし、例外もあって、外部サイトから配信される静的ファイルを利用する際には static テンプレートタグを利用してはいけないので、この点には注意してください。

static テンプレートタグは、あくまでも、そのウェブアプリ(もしくは、そのウェブアプリが動作しているサーバーマシン)が配信する静的ファイルを扱うことを指示するタグで利用するものとなります。例えば、外部のウェブサイト(CDN 等含む)が配信している静的ファイルを扱う場合は、static テンプレートタグは利用せず、直接扱いたい静的ファイルの絶対パスを URL に指定する必要があります。

staticテンプレートタグを利用する場合と利用しない場合の説明図

例えば、Bootstrap の CSS は、外部のウェブサイトから配信されている静的ファイルとなりますので、この CSS を読み込みたい場合は、テンプレートファイルには下記のようなタグを記述する必要があります。

BootstrapのCSSの読み込み
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" 略>

このように、外部のサイトから読み込むようなファイルは、それが静的ファイルであったとしても、static テンプレートタグを利用してはいけないので注意してください。static テンプレートタグによって変換される URL は、あくまでも、自分自身のウェブアプリ(サーバーマシン)に対するリクエストの URL となります。

静的ファイルを配信する手順(公開用ウェブサーバー)

次は、本番環境のウェブサーバーで静的ファイルを配信する手順について解説していきます。

ただ、おそらく、このページを読んでくださっているのは Django 入門者の方であって、すぐにウェブアプリを本番環境に移行して公開・運用していくことは無いのではないかと思います。また、特にウェブサーバーの設定はウェブサーバーの種類によって異なるため一概には説明できません。そのため、特にウェブサーバーの設定に関しては、設定のイメージのみを伝える形で解説を行わせていただきます。

また、本番環境には、既にウェブサーバーや Django がインストールされていることを前提に解説を進めますので、その点はご注意ください。

STATIC_ROOT を定義する

まずは、プロジェクトの settings.pySTATIC_ROOT を新規に定義します。この STATIC_ROOT は、最終的には本番環境での「静的ファイルの取得先」となるフォルダとなり、後述の collectstatic コマンドにより、静的ファイルが全て STATIC_ROOT 以下にコピーされることになります。この静的ファイルの取得先として適切なフォルダを選び、そのフォルダのパスを値とする STATIC_ROOT を下記のように定義してください。

STATIC_ROOTの定義
STATIC_ROOT = '/var/www/html/static/'

本番環境にプロジェクトをコピーする

次に、開発環境で開発したウェブアプリのプロジェクト一式を本番環境にコピーします。ウェブアプリを動作させるためには views.pymodels.py 等のソースコードや、このページで解説している静的ファイル等も一緒にコピーする必要があります。

プロジェクト一式を本番環境にコピーしてくる様子

Git 等の構成管理を利用して、開発したプロジェクトをすぐに本番環境にコピーできるようにしておくと便利だと思います。

collectstatic コマンドを実行する

開発環境から本番環境に移行する際に、静的ファイルを配信するために実施しなければならない手順の1つが collectstatic コマンドの実行となります。

collectstatic コマンドは、開発環境で開発用ウェブサーバーから配信される全ての静的ファイルを、先ほど定義した STATIC_ROOT に集約するコマンドになります。

前述の通り、開発環境で使用する開発用ウェブサーバーでは、複数の「静的ファイルの取得先」が存在し、アプリ毎に静的ファイルを設置することが可能です。また、この「静的ファイルの取得先」は追加することも可能です。collectstatic コマンドを実行すれば、それらの全ての「静的ファイルの取得先」の中に設置された静的ファイルが STATIC_ROOT 以下にコピーされて1つのフォルダに集約されることになります。

開発用ウェブサーバーにおける「静的ファイルの取得先」に設置されたファイルがSTATIC_ROOT以下に集約される様子

collectstaticmanage.py から実行するコマンドとなりますので、下記のような形式のコマンドから実行することになります。

% python manage.py collectstatic

上記のようにコマンドを実行すれば、開発環境で配信される全ての静的ファイルが STATIC_ROOT 以下にコピーされることになります。また、このコマンドを実行した場合には、「静的ファイルの取得先」以下のフォルダ構成を保ったままコピーが実施されることになります。

また、collectstatic を実行すれば、下記ページで解説した管理画面用の静的ファイルも一緒に STATIC_ROOT 以下にコピーされることになります。

Djangoの管理画面の使い方の解説ページアイキャッチ 【Django入門11】管理画面(admin)の使い方の基本

ウェブサーバーの設定を変更する

collectstatic の実行により、開発用ウェブサーバーで配信していた静的ファイルが全て、STATIC_ROOT 以下に集められることになります。

あとは、「静的ファイルであることを示す URL のプレフィックス」と「静的ファイルの取得先」をウェブサーバーに設定してやれば良いだけです。で、先ほど、collectstaticSTATIC_ROOT 以下に静的ファイルが集められたわけですから、後者に関しては STATIC_ROOT と同じパスを指定してやれば良いことになります。

公開用ウェブサーバーの静的ファイルの取得先としてSTATIC_ROOTを指定する

また、「静的ファイルであることを示す URL のプレフィックス」に関しては、開発用ウェブサーバーと同じものを設定してやれば良いです。開発用ウェブサーバーにおける「静的ファイルであることを示す URL のプレフィックス」は STATIC_URL (or '/' + STATIC_URL) で定義されています。したがって、公開用ウェブサーバーにおいても、STATIC_URL を「静的ファイルであることを示す URL のプレフィックス」として設定してやれば良いことになります。

STATIC_URLから始まるURLを静的ファイルに対するリクエストのURLと判断するように設定する

なので、結局、settings.py で設定した STATIC_URLSTATIC_ROOT を使ってウェブサーバーの設定も行えば良いことになります。

簡単に具体例を示すと、STATIC_URL = 'static/' かつ STATIC_ROOT = '/var/www/html/static/ である場合、 Nginx においては、設定ファイルに下記のような設定の追記を行うことになります。

Nginxでの設定例
server {
    〜略〜

    location /static/ {
        alias /var/www/html/static/;
    }

    〜略〜
}

また、Apache においては、設定ファイルに下記のような設定の追記を行うことになります。

Apacheでの設定例
Alias /static/ /var/www/html/static/

<Directory /var/www/html/static>
Require all granted
</Directory>

設定先のファイル等の詳細な解説はここでは行いませんが、いずれにしても、STATIC_URLSTATIC_ROOT に指定した値を用いて設定することで、開発用ウェブサーバーと時と同様の静的ファイルの配信を公開用ウェブサーバーでも実現できることになります。今後、実際にウェブアプリを公開する手順等も解説する機会があると思いますので、そこでウェブサーバーの設定の詳細も解説するようにしたいと思います。

スポンサーリンク

静的ファイルを扱う手順のまとめ

説明が長くなってしまったので、ここで静的ファイルを扱う手順について簡単にまとめておきます。

まず、ウェブアプリで静的ファイルを扱えるようにするために最低限必要なことは下記の2つです。本番環境のウェブアプリで静的ファイルを扱うためには別途他の手順も必要なのですが、まずは下記の手順を実施して開発環境で静的ファイルを扱うことの可能なウェブアプリを実現することを目指すので良いと思います。

  • 「静的ファイルの取得先」に配信したい静的ファイルを設置する
  • テンプレートファイルに静的ファイルを扱うことを指示するタグを記述する
    • (URL は static テンプレートタグを利用して指定する)
    • static の引数には、静的ファイルの「静的ファイルの取得先」からの相対パスを指定する)

settings.py における STATIC_URL の変更や STATICFILES_DIRS の定義の追加に関しては、必要な場合のみ行えば良いです。

また、本番環境に移行する際には別途他の手順も必要となりますが、ここまで説明してきた手順で静的ファイルを扱うウェブアプリを実現していけば本番環境への移行もスムーズに行うことができます。特に STATIC_URLSTATIC_ROOT の意味合いを理解しておけば、本番環境への移行時に必要となるウェブサーバーの設定も簡単に実施できますので、この辺りの意味合いはしっかり理解しておきましょう!

掲示板アプリで静的ファイルを扱う

最後に、掲示板アプリで静的ファイルを扱う例を示していきたいと思います。

この Django 入門 の連載の中では簡単な掲示板アプリを開発してきており、前回の連載では下記ページで CRUD 操作の追加を行いました。

【Django入門16】CRUDの実現(Create・Read・Update・Delete)

今回は、上記ページの 掲示板アプリで CRUD 操作を実現する で示したアプリを、静的ファイルとして画像と CSS を扱うように変更していきたいと思います。ただし、静的ファイルの配信は開発用ウェブサーバーで実施します。

掲示板アプリのプロジェクト一式の公開先

この Django 入門 の連載を通して開発している掲示板アプリのプロジェクトは GitHub の下記レポジトリで公開しています。

https://github.com/da-eu/django-introduction

また、前述のとおり、ここでは前回の連載の 掲示板アプリで CRUD 操作を実現する で作成したプロジェクトをベースに変更を加えていきます。このベースとなるプロジェクトは下記のリリースで公開していますので、必要に応じてこちらからプロジェクト一式を取得してください。

https://github.com/da-eu/django-introduction/releases/tag/django-crud

さらに、ここから説明していく内容の変更を加えたプロジェクトも下記のリリースで公開しています。以降では、基本的には前回からの差分のみのコードを紹介していくことになるため、変更後のソースコードの全体を見たいという方は、下記からプロジェクト一式を取得してください。

https://github.com/da-eu/django-introduction/releases/tag/django-staticfile

スポンサーリンク

静的ファイルの配信の実現

まずは、開発用ウェブサーバーから静的ファイルが配信されるよう、準備を行なっていきます。

静的ファイルの用意

最初に、アプリで扱う静的ファイルを用意していきます。

今回は、前述の通り、掲示板アプリを変更し、画像と CSS を扱えるようにしていきますので、画像ファイルと CSS ファイルを用意しておく必要があります。

画像ファイルとしては、正直なんでも良いのですが、とりあえず下記をダウンロードし、logo.png というファイル名で保存しておいてください。

ロゴ画像のサンプル

さらに、CSS ファイルとしては、下記を style.css というファイル名で保存しておいてください。

style.css
.logo {
    text-align: right;
}

.mini {
    width: 10%;
}

静的ファイルの設置

続いて、先ほど保存したファイルをプロジェクト内に設置していきます。

現状の掲示板アプリは、基本的には forum の1つのアプリのみから構成されています。1つのアプリで構成されているため、プロジェクト内で共通的に利用するファイルと、アプリ固有で利用するファイルに差異はないのですが、STATICFILES_DIRS の定義例を示すため、画像はプロジェクト内で共通的に利用するファイルとみなし、プロジェクトフォルダ内に設置するようにしていきたいと思います。CSS に関しては、アプリフォルダ内に設置するようにしていきます。

ということで、まずは下記の2つのフォルダを作成してください。

test_project/static/img/
test_project/forum/static/forum/css/

フォルダの作成位置を図示すると下図のようになります。test_project フォルダが2つありますが、上側の階層の test_project 直下に static フォルダを作成するようにしてください。

静的ファイルを設置するフォルダを作成する様子

さらに、前者のフォルダ内に logo.png を、後者のフォルダ内に style.css を設置してください。

配信する静的ファイルを設置する様子

STATICFILES_DIRS の定義

先ほどの logo.pngstyle.css の設置によって、style.css に関しては、既に配信可能な状態となっています。これは、開発用ウェブサーバーの「静的ファイルの取得先」として、デフォルトで下記フォルダが設定されているからになります。この「静的ファイルの取得先」に設定されているフォルダ以下に設置されているファイルは、開発用サーバーによって配信可能な状態となります。

test_project/forum/static/

ですが、現状だと logo.png は「静的ファイルの取得先」となるフォルダ以下に設置されていないため、配信不可の状態となります。そのため、STATICFILES_DIRS の定義を行い、「静的ファイルの取得先」として下記を追加することで、logo.png が配信可能な状態にしていきたいと思います。

test_project/static/

ということで、プロジェクトの settings.py を開き、下記の追記を行ってください。おそらく、現状の settings.py では STATIC_URL が定義されていると思います。その下に追記を行えば良いです。

STATICFILES_DIRSの定義
import os
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static/'),
]

上記における BASE_DIR はプロジェクトフォルダのパスとなりますので、この定義により、下記フォルダが新たな「静的ファイルの取得先」として設定されることになります。そして、下記フォルダ以下に設置している logo.png が開発用ウェブサーバーによって配信されるようになったことになります。

test_project/static/

ということで、以上の手順によって、logo.pngstyle.css を配信する準備が整ったことになります。

スポンサーリンク

静的ファイルの配信の動作確認

ここで、先ほど設置した logo.pngstyle.css が正常に配信されているかどうかを確認しておきたいと思います。

静的ファイルが配信されているかどうかの確認は、わざわざ HTML を作成しなくても、ウェブブラウザの URL バーに直接静的ファイルの URL を「絶対パス」で指定してやることで実施できます。

ということで、まずは下記のコマンドで開発用ウェブサーバーを起動しましょう!静的ファイルは開発用ウェブサーバーによって配信されるのですから、静的ファイルの配信の動作確認を行うためには開発用ウェブサーバーの起動が必要です。

% python manage.py runserver

開発用ウェブサーバーが起動したら、次はウェブブラウザのアドレスバーに下記の URL を入力してエンターキーを押してみてください。

http://localhost:8000/static/img/logo.png

logo.png が配信されるようになっていれば、下図のように logo.png の画像が表示されるはずです。

ウェブブラウザでlogo.pngを取得して表示した様子

さらに、次はウェブブラウザのアドレスバーに下記の URL を入力してエンターキーを押してみてください。

http://localhost:8000/static/forum/css/style.css

style.css が配信されるようになっていれば、下図のように style.css の中身が表示されるはずです。

ウェブブラウザでstyle.cssを取得して表示した様子

これらが確認できれば、開発用ウェブサーバーからの静的ファイルの配信が実現できていることを確認できたことになります。後は、これらの静的ファイルがウェブアプリで扱われるように、テンプレートファイルを作成してやれば良いだけになります。

テンプレートファイルの変更

ということで、次はテンプレートファイルの変更を行っていきます。今回は、forum/templates/forum/ に設置されている base.html を、下記のように変更したいと思います。

base.html
{% load static %}
<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'forum/css/style.css' %}">
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <header>
        <nav class="navbar navbar-expand navbar-dark bg-primary">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item">
                    <a class="nav-link navbar-brand" href="{% url 'index' %}">掲示板</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'users' %}">ユーザー一覧</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'comments' %}">コメント一覧</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'post' %}">コメント投稿</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'register' %}">ユーザー登録</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'login' %}">ログイン</a>
                </li>
                <li class="nav-item">
                    <form id="logout-form" method="post" action="{% url 'logout' %}">
                        {% csrf_token %}
                        <button class="btn btn-link nav-link" type="submit">ログアウト</a>
                    </form>
                </li>
            </ul>
        </nav>
    </header>
    <main class="container my-5 bg-light">
        {% block main %}{% endblock %}
    </main>
    <footer>
        <div class="logo">
            <img class="mini" src="{% static 'img/logo.png' %}">
        </div>
    </footer>
</body>
</html>

以前の base.html から、新たにフッター(footer タグ)を追加し、そこに logo.png の画像を表示するようにしています。さらに、ヘッダーで新たに style.css を読み込むようにし、フッター及び画像(logo.png)に対して style.css で定義されたスタイルを適用するようにしています。このスタイルの適用により、画像の幅がページの幅の 10 % 分のサイズとなり、さらに画像がページの右端に表示されるようになります。

base.htmlの変更の説明図

また、この base.html は、掲示板アプリの他の全テンプレートファイルから継承される親テンプレートファイルとなっていますので、base.html への変更は、掲示板アプリの全ページに適用されることになります。

上記の base.html の変更点のポイントの1つは、ファイル内にテンプレートタグ {% load static %} を記述している点で、この記述が無い状態だと static テンプレートタグ利用時に例外が発生することになるので注意してください。

また、base.html に新たに追加したタグで、下記のように静的ファイルの URL を static テンプレートタグを利用して指定している点もポイントとなります。

取得する静的ファイルのURL1
<link rel="stylesheet" href="{% static 'forum/css/style.css' %}">
取得する静的ファイルのURL2
<img class="mini" src="{% static 'img/logo.png' %}"

さらに、下記に関しては static テンプレートタグを利用していない点もポイントになります。外部サイトからの静的ファイルの取得 で解説したように、外部のサイトから静的ファイルを取得して利用する場合は、static テンプレートタグの利用は不要となります。

外部サイトからの静的ファイルの取得
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" 略>

ソースコードの変更は以上となります。

静的ファイルの利用の動作確認

最後に、静的ファイルがウェブアプリで利用できるようになっていることを確認していきましょう!

先ほどの静的ファイルの配信の動作確認時同様に、まずは下記コマンドを実行して開発用ウェブサーバーを起動してください(既に起動している場合はコマンドの実行は不要です)。

% python manage.py runserver

さらに、下記の URL をウェブブラウザに指定してログインページを表示してみましょう!

http://localhost:8000/forum/login/

下図のように、ログインページの下側には logo.png が表示されていることが確認できると思います。

ログインページにlogo.pngが表示される様子

このように logo.png が表示されるのは、base.html に追記した img タグによって logo.png の取得のリクエストがウェブブラウザから送信され、さらに開発用ウェブサーバーによって配信された logo.png を取得してウェブブラウザが画像として表示してくれているからになります。

logo.pngに対するリクエストが送信される流れ

また、表示される logo.png の幅がページの約 10 % となっており、さらにページの右端に表示されていることが確認できると思います。これは、logo.png 同様に link タグによって style.css が取得され、その style.css で定義されるスタイルがページの要素に適用されているからになります。

つまり、先ほど示した図のように logo.png が表示されていれば、静的ファイルを扱うウェブアプリが実現できていることを確認できたことになります!

最後に、開発用ウェブサーバーからの出力結果を確認してみてください。開発用ウェブサーバーでは、受け取ったリクエストのメソッドや URL が標準出力に出力されるようになっています。そして、おそらく、下記のような出力が行われていることが確認できると思います。

[29/Nov/2024 09:37:14] "GET /static/forum/css/style.css HTTP/1.1" 200 59
[29/Nov/2024 09:37:14] "GET /static/img/logo.png HTTP/1.1" 200 13515

この出力結果の、特に URL の先頭部分がポイントになります。これらのリクエストはログインページ表示時に取得した HTML のタグに従って送信されており、そのタグの URL は static テンプレートタグを利用して指定しているため、URL の先頭には STATIC_URL で指定された文字列が結合されていることになります。

さらに、開発用ウェブサーバーは、URL の先頭が STATIC_URL である場合に静的ファイルの取得を行なって返却するようになっていますので、上記のような URL のリクエストの送信によって、静的ファイルの取得を行うことができるようになっています。

このように、静的ファイルを扱うためには、静的ファイルに対するリクエストであるとウェブサーバーに判断される URL が HTML のタグに指定されていることが重要で、これは static テンプレートタグの利用によって実現できます。

もちろん、STATIC_URL に指定する文字列を変更すれば、開発用ウェブサーバーが静的ファイルであると判断する URL も変化することになりますが、STATIC_URL に従って static テンプレートタグによって結合される文字列も変化することになりますので、リクエストの URL は変化するものの、静的ファイルは変更前と変わらず利用可能です。是非、この辺りの設定も変更してみて、ウェブアプリ等の動作がどのように変化するのかを確認してみてください!

スポンサーリンク

まとめ

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

結論としては、Django で開発するウェブアプリが開発環境で静的ファイルを扱えるようにするためには、最低限、下記を実施すれば良いだけになります。

  • 「静的ファイルの取得先」に配信したい静的ファイルを設置する
  • テンプレートファイルに静的ファイルを扱うことを指示するタグを記述する
    • (URL は static テンプレートタグを利用して指定する)
    • static の引数には、静的ファイルの「静的ファイルの取得先」からの相対パスを指定する)

なんですが、開発環境から本番環境に移行するためにはウェブサーバーの設定が必要となり、この設定を行うためには、ウェブアプリで静的ファイルが扱われる時の動作や仕組みに関しても理解しておいた方が良いと思います。この辺りに関しても、このページで解説していますので、本番環境への移行に困った際には、このページの内容を思い出していただければと思います!

静的ファイルを扱うことができれば、開発可能なウェブアプリの幅も広がりますので、是非 Django で開発するウェブアプリでの静的ファイルの扱い方はマスターしておきましょう!

また、静的ファイルを扱うことができれば、同様の考え方によってファイルのアップロードや、アップロードされたファイルを扱うウェブアプリの開発も行うことができるようになります。

特に、画像ファイルのアップロードに関して下記ページで解説を行っていますので、詳しく知りたい方は下記ページを読んでみてください!

Djangoでの画像のアップロードの実現方法解説ページアイキャッチ 【Django】画像をアップロードする

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です