0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Python(Django) x Docker x AWSAdvent Calendar 2023

Day 21

【Django】staticファイルの404エラーはDEBUGをTrueにすれば良い

Posted at

概要

Djangoをローカル環境で起動したら、なぜかJSなどの静的ファイルが読み込まれない404エラーに...。
おかしいなぁ本番環境では正常に動いているプログラムなのに...と思ったら、思わぬところに原因がありました。

原因はDEBUG設定

原因は、DjangoのDEBUG設定にありました。
settings.pyで明示的にDEBUG=Trueと追記したら無事に読み込まれるようになりました。

調べてみると多くの場所で既にこの現象の対応策が書かれていました。
stackoverflowでもそんなコメントが盛りだくさん。

On localhost, make sure to define DEBUG = True on settings.py
引用元:Django Static files 404

また、以下の記事にはこのように記載がありました。

DEBUG=True と設定すると、本来Webサーバーを経由してstaticやmediaのファイルを読み込むところをdjangoアプリ内のstaticとmediaを見に行くように設定することができます。
引用元:【Django】debug=False設定時staticとmediaのファイルが読み込めない事象の解決

なぜDEBUG設定でSTATICが読めるようになるのか?

DEBUG = Falseの状態では、Djangoは静的ファイルを提供するための役割を持っていません。

じゃあ、本番環境ではFalseにしているけどどうしているの?といえば、静的ファイルを提供するのは通常、Webサーバー(NginxやApacheなど)の役割です。
Django自体が「静的ファイルの提供」という責任を持たない設計思想なのです。Webサーバに任せた方が効率的で高速だから、でしょう。

では、開発環境では一体誰が静的ファイルを提供してくれているのか?
というと、Django内蔵の開発用Webサーバー(runserver)です。

「え、python manage.py runserver 0.0.0.0:8000みたいなコマンド使ってないんだけど!?」っというケースもあるかもですが、DEBUG=Trueに設定すると、このrunserverが使用されるようになります。
そして、このサーバによって静的ファイルが提供されるようになるのです。
逆を言えば、Webサーバを使わない開発環境下では、runserverを使わないと静的ファイルが読み込まれません。
(nginxのdockerを利用してconfで設定するという方法もありますので、これは別途また記事にしたいと思います。あとは静的ファイル提供用のPythonライブラリもあるみたいです)

ただし、言わずもがな、デバッグ内容が本番でも見れると、詳細なシステム情報を取得されてしまう可能性があるので本番では使いません。Django公式ドキュメントにもrunserverが自動的に動いてくれていることが書いてありますし、もちろん、開発環境でのみの利用が推奨されています。

During development, if you use django.contrib.staticfiles, this will be done automatically by runserver when DEBUG is set to True (see django.contrib.staticfiles.views.serve()).

This method is grossly inefficient and probably insecure, so it is unsuitable for production.

runserverはどんな流れで処理しているのか?

処理の流れとしては以下になっていると考えられます。

①runserverがSTATIC_URL(settings.pyで行う/static/とかのこと)のリクエストをクライアントから受け取る
②Djangoはそれを確認し、静的ファイルとみなす
③runserverは設定ファイル(settings.py)で定義されたSTATIC_ROOTのパスを確認し、静的ファイルのルートディレクトリとして使用
④リクエストされた静的ファイルがSTATIC_ROOT内に見つかった場合、runserverはそのファイルをクライアント(ブラウザなど)に返す

staticファイルをnginxから見せるような手間がいらなくなるので、ローカル環境で行う場合はrunserverを使った方が良いケースが多いかと思います。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?