Djangoで静的ファイル(イメージファイル、CSSファイル、Javascriptファイル)を使用する方法
記事No.63
更新日時2023年03月10日

バイオレットちゃん
では今回は、DjangoでCSSファイルなどの静的ファイルを扱う方法を解説するね。

スカーレット

バイオレットちゃん
そうだよ!そういったファイルも問題なく扱えるよ!

スカーレット
設定方法
STATICFILES_DIRの使い方
STATIC_ROOTの使い方
この記事で分かる事
■記事ページを表示中
記事No.63
更新日時2023年03月10日
バイオレットちゃん
では今回は、DjangoでCSSファイルなどの静的ファイルを扱う方法を解説するね。
スカーレット
バイオレットちゃん
そうだよ!そういったファイルも問題なく扱えるよ!
スカーレット
この記事で分かる事
Djangoで静的ファイルを使用するには、以下のファイルを編集します。
まず最初に、index.htmlの一番上の行に、以下を記述します。
{% load static %}
{% %}で挟んで記述された部分を、「テンプレートタグ」と言います。上記の場合、loadテンプレートタグを使用しています。loadテンプレートタグは他のテンプレートタグを読み込む時に使います。上記の場合、loadテンプレートタグを使用してstaticテンプレートタグを読み込んでいます。
次に、読み込みたい静的ファイルを指定します。
今回は例として、CSSファイルを指定します。
<link rel="stylesheet" href="{% static 'appdir/css/style.css' %}" />
上のコードを見ると、先程loadテンプレートタグで読み込んだstaticテンプレートタグが使われている事が分かります。
staticテンプレートタグは、Djangoでレンダリングされると「staticフォルダへのパス」に変換されます。
「staticフォルダへのパス」は、urls.pyファイルで設定します。
Djangoは、クライアントからリクエストがあった時、今回記述したテンプレートタグをレンダリングしてHTMLファイルを生成します。そして、生成したHTMLファイルを送り返します。
ですので、
<link rel="stylesheet" href="{% static 'appdir/css/style.css' %}" />
とテンプレートタグを記述した場合でも、クライアントに返されるHTMLファイルは、
<link rel="stylesheet" href="/static/appdir/css/style.css" />
のようになります。
index.htmlへの記述が完了したら、次はurls.pyを設定します。
Djangoには、プロジェクトフォルダ内とアプリケーションフォルダ内それぞれにurls.pyファイルがありますが、ここで編集するのは、アプリケーションフォルダ内のurls.pyのほうです。
スカーレット
バイオレットちゃん
まずはモジュールをインポートします。
from django.conf import settings from django.conf.urls.static import static
from django.conf import settingsで、Djangoのプロジェクトフォルダ内にあるsettings.pyを読み込んでいます。
スカーレット
バイオレットちゃん
urlpatternsを編集してインポートしたstaticを追加します。
staticの第一引数には、「staticフォルダへのパス」、第二引数には、「document_root=」と「staticフォルダのドキュメントルート」を記述します。
urlpatterns = [path('', views.index, name='index')] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
この例の場合、staticフォルダへのパスが「settings.STATIC_URL」でstaticフォルダへのドキュメントルートが「settings.STATIC_ROOT」となります。
フォルダへのパスと、ドキュメントルートには次の関係があります。フォルダへのパスにアクセスがあった場合、実際に参照されるのはドキュメントルートに指定されたフォルダ。つまり、クライアント(ブラウザ)に表示されるのがフォルダへのパスで、そのパスへアクセスすると、サーバー内のドキュメントルートで指定されたフォルダを見る事ができます。
先程、index.htmlに記述した、
<link rel=”stylesheet” href=”{% static ‘appdir/css/style.css’ %}” />
の部分の、staticテンプレートタグは、DjangoでレンダリングされHTMLに変換されると、urls.pyに記述したstaticの第一引数に指定したフォルダへのパスに書き換わります。
今回の場合、第一引数に指定したフォルダへのパスは、「settings.STATIC_URL」となっています。
現段階では、settings.STATIC_URLにパスが代入されていないので、settings.pyファイルを編集して、settings.STATIC_URLにパスを代入します。
settings.pyの最後の行に以下を記述します。
STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] #STATIC_ROOT = os.path.join(BASE_DIR, 'static')
urls.pyでインポートしたsettingsは、ここで編集するsettings.pyファイルの事です。
urls.pyで、staticの第一引数に、変数settings.STATIC_URLを指定しましたが、この変数に’/static/’を代入します。
同じく、staticの第二引数に、変数document_root=settings.STATIC_ROOTを指定しましたが、この変数に、[os.path.join(BASE_DIR, ‘static’)]が入ります。
第二引数で指定したのは、settings.STATIC_ROOTでしたが、Djangoの仕様により、STATIC_ROOTの代わりに、STATICFILES_DIRが参照されます。
[os.path.join(BASE_DIR, 'static')]は、manage.pyのあるフォルダ(BASE_DIR)内にあるstaticフォルダと、各アプリケーションフォルダ内にあるstaticフォルダを参照しています。
スカーレット
バイオレットちゃん
後で詳しく解説するけど、STATIC_ROOTはデプロイ時しか使わないからだよ!
スカーレット
settings.pyで指定したSTATICFILES_DIRS = [os.path.join(BASE_DIR, ‘static’)]は開発中のみ参照されます。
本番環境では参照されないドキュメントルートです。
開発中は、各アプリケーションフォルダの中にstaticフォルダを入れて、その中で、imageファイルや、cssファイル、javascriptファイルを管理します。
STATICFILES_DIRS = [os.path.join(BASE_DIR, ‘static’)]は、それらアプリケーションフォルダ内にあるstaticフォルダを参照するドキュメントルートです。
settings.py内で、DEBUG = Falseとなっている場合は、STATICFILES_DIRSは参照されません。STATICFILES_DIRSは開発中しか参照されない為です。DEBUG = Trueは、開発環境である事を意味し、エラーがあった場合に、そのエラー内容を表示させる事ができます。DEBUG = Falseは、本番環境である事を意味し、デプロイする際はDEBUG = Falseとします。
開発環境では、動的なファイルも静的なファイルもすべてDjangoがレスポンスを返していましたが、本番環境では、動的なファイルが要求された時のみDjangoにリクエストを送り、静的なファイルはNGINXなどのウェブサーバーがレスポンスを返すように設定します。
上の図のように、開発環境の場合、静的ファイル(静的コンテンツ)も動的ファイル(動的コンテンツ)もDjangoが返していました。
本番環境では、上の図のように静的ファイルのリクエストがあった場合はDjangoを使わずにウェブサーバーが単体でファイルを返します。動的ファイルのリクエストがあった場合のみDjangoにリクエストを送ります。
バイオレットちゃん
そういう事!ちなみに、ウェブサーバーは、クライアントからのリクエストが、静的ファイルを求めているのか、動的ファイルを求めているかは、ウェブサーバーにアクセスしたURLによって判別しているよ。hoge.com/staticから始まるURLにアクセスしてきた場合は静的ファイルを求めている。それ以外のURLにアクセスしてきた場合は動的ファイルを求めている。といった具合です。
スカーレット
バイオレットちゃん
例えば、クライアントが画像ファイル(静的ファイル)をリクエストした場合は、ウェブサーバーがレスポンスを返しますが、クライアントから送られてくる値によって返されるファイルが変わるような動的なファイルをリクエストした場合は、ウェブサーバーは、Djangoが動いているアプリケーションサーバーに仕事を振り、Djangoが処理できる設定をします。
このように仕事を振り分けたほうが、静的ファイルを速く返せる為、DJangoでは、このような仕様になっています。
バイオレットちゃん
NGINXなどのウェブサーバーを使った事があるなら、クライアントからのリクエストを直接ウェブサーバーで返したり、アプリケーションサーバーに振り分けたりした経験があるからイメージしやすいと思うけど、そういった経験が無い場合は、理解するのちょっと難しいかも。
スカーレット
Djangoで作成したサービスをデプロイする時は、ウェブサーバーに、静的なファイルを置くフォルダを用意しておきます。
静的なファイルをウェブサーバーに置いておく事で、静的なファイルをリクエストされた際、ウェブサーバーのみで対応が可能になるからです。
上の図のように、ウェブサーバーにDjangoプロジェクトフォルダを配置し、そのフォルダの中にあるstaticフォルダに静的なファイルを集めておくと管理がしやすいです。
各アプリケーションフォルダ内のstaticフォルダにある静的ファイルを、プロジェクトフォルダ内のstaticフォルダに集めるコマンドが、collectstaticです。manage.pyがあるフォルダ内(プロジェクトフォルダ)で以下を実行します。
python manage.py collectstatic
collectstaticコマンドは、settings.pyに記述したSTATIC_ROOTに、各アプリケーション内のstaticフォルダにある静的ファイルを全て集めてくれます。
Django管理画面のCSSが本番環境で反映されない場合、collectstaticコマンドで管理画面アプリケーションの静的ファイルを集めていないからです。
スカーレット
バイオレットちゃん
settings.pyに以下のように記述すると、STATIC_ROOTを設定する事ができます。
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
この例の場合、BASE_DIR(manage.pyがあるフォルダ)内にあるstaticフォルダが指定されています。
STATIC_ROOTは、collectstaticコマンドを使用する時だけ参照できるようにすれば良いので、開発時はコメントアウトしておいて下さい。
スカーレット
NGINXなどでウェブサーバーを構築する際は、静的なファイルへのアクセスは、STATIC_ROOTで指定したドキュメントルートを参照するように設定します。
名前:スカーレット
2010年からWEBサイトやWEBアプリを作成しています。最初は趣味でブログを書いていましたがSEOを勉強するのが楽しくなり、そのままブロガーとして独立しました。その後、記事を書くだけでは物足りなくなり自分でWEBアプリの作成をスタート。現在はブロガー兼プログラマーとして活動しています。このWEBアプリ(ブロトーク)もDjangoで自作しました。ブロトークはブログとSNSを合体させたようなWEBアプリです。ブログを読んで気づいた事や感想などあれば、気軽にメッセージを送って頂ければと思います。WEB技術を一緒に勉強していけたらと思います。
コメントフォーム