Djangoでの静的ファイルの設定について
Djangoでの静的ファイル(画像、CSS、Javascript)の設定について
部内での講習会で、Djangoでimgタグを使用するために画像ファイルをどこに置いた方がいいかと質問されたときにちゃんと答えられなかったので備忘録もかねてまとめておこうと思いました。
Djangoだと単純にパスを指定するだけじゃないので意外と詰まるかもなと感じました。(実際自分もしっかりと忘れてました、、)
Djangoチュートリアル
Djangoによるアプリの立ち上げやページの表示方法について
imgタグのあれこれ
まずはおさらいとしてDjangoを使わない通常のHTMLでの画像の表示方法について説明します。
HTMLで画像を表示するときは一般的にはimgタグを使用します。
imgは閉じタグのみで使用します。
また属性の設定をすることで、表示する画像に対して色々な設定ができます。
下のコードのように使います。 この例では画像とHTMLファイルの位置関係は以下のようになっています。
作業ディレクトリ
├─ index.html
└─ images
└─ django.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="./images/django.png", width="50", height="50" alt="画像"/>
</body>
</html>
これでエクスプローラー内のindex.htmlをダブルクリックして直接HTMLファイルをブラウザに表示してみてください。
ブラウザ上で画像が表示されているはずです。
imgタグのの属性(追加設定)は主にこんな感じです。
src属性
使いたい画像がどこに置いてあるかをパスで指定します。
パスってなにー?って人用にわかりやすく解説している記事があったので置いておきます。
絶対パスと相対パス | HTML 入門 | レッスン
alt属性
画像がうまく表示できなかった際に代わりに表示されるテキストを設定する。
width, height
画像サイズの調製に使われる。数値でも%でも
Djangoでの静的ファイルの扱い
ここから本題のDjangoでの画像表示についてです。
ここでの画像表示とは、ユーザーがデータベースなどにアップロードした画像を扱う場合ではなく、
あらかじめ用意された画像・CSS・JavaScript などの、変更されることのないファイルの取り扱いについて説明します。
こういったあらかじめ用意されたファイルのことをDjangoでは静的ファイル(static files)といいます。
Djangoでこれらの静的ファイルを利用する場合、先ほどのように自由なところにおいてそのパスを指定するような方法では利用できません。
Djangoではこれらのファイルを決まった場所に設置して管理を行います。
静的ファイルの管理はdjango.contrib.staticfilesという機能によって管理されています。(開発者が意識する必要は少ないので覚えなくて問題ないです。)
staticfilesによって静的ファイルは特定の場所に集められ、そのパスを指定することで簡単にDjango上で画像などを使用することができます。
静的ファイルの設定
staticfilesが自動的にファイルを収集するためにいくつか設定をします。
まずdjango.contrib.staticfilesがsettings.pyのINSTALLED_APPSに含まれているかを確認します。
デフォルトで設定されているため、確認する程度で問題ないです。
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles", ← 確認できる。
"app.apps.AppConfig"
]
ここに記述されることでプロジェクト全体にstaticfilesがインストールされます。
次に静的ファイルを管理する場所を設定します。
settings.pyで以下のような記述が存在するか確認してください。
STATIC_URL = "static/"
デフォルトでは上のように記述されているはずです。
これは静的ファイルがstaticというフォルダ内に管理されていることを示しています。
静的ファイルの設置
ここまで設定ができたらディレクトリを作成します。
STATIC_URL = "static/"としたため、staticディレクトリを作成する。 ここでディレクトリは各アプリごとに作成します。(今回の場合はappディレクトリ直下に)
作成後はこのようになっているはずです。(一部抜粋)
testproject
├─ app
│ ├─ static
│ └─ templates
└─ testproject
このstaticディレクトリ内に画像やCSS、Javascriptファイルなどを格納することでDjangoのテンプレートで使用することができる。
テンプレートでの呼び出し
静的ファイルの設置が完了したのでいよいよテンプレート側で呼び出します。
index.htmlに以下の記述を追加します。
{% load static %} ← 追加
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="{% static 'django.png' %}" alt="Sample Image"> ← 追加
</body>
</html>
これでpython manage.py runserverコマンドでサーバを起動すると画像が表示されるはずです。
{% %}
これはDjangoのテンプレートでプログラムなどを書くときに使用するタグです。
{% load static %}
静的ファイルの読み込みを行います。
{% static 'django.png' %}
staticという変数はSTATIC_URLを示します。
よってこれはstatic/django.pngというパスを生成しています。
Djangoではこの制御文を使用して静的ファイルのパスを指定します。
共通の静的ファイルを設定する
各アプリごとではなく、プロジェクト全体で使用する静的ファイルの設定をする場合にはsettings.pyに以下の記述を追加します。
import os
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
これで以下のように共通の静的ファイルの配置ができます。
testproject
├─ static
│ ├─ css
│ │ └─ style.css
│ └─ js
│ └─ script.js
├─ app
│ └─ static
│ └─ image
│ └─ image.png
└─ testproject
共通静的ファイルの呼び出し方は今までの方法と同じです!
おまけ(詳しいお話)
どうしてこのような設定が必要なのかについて少し簡単にお話しします!
そもそも画像などの静的ファイルをDjangoのようなバックエンドが配信すること自体があまりいい方法ではないとされています。
Djangoなどでは静的ファイルの配信には処理が最適化いないため、大量のアクセスによってパフォーマンスが大きく落ちてしまいます。
また、セキュリティ面でもあまり推奨されていない方法です。Djangoがファイルの配信を担当すると、意図しないファイル(セキュリティ上公開してはいけないもの)を外部からアクセスされる可能性もあるためです。
開発中はrunserverなどでローカルにサーバーを立ち上げているため問題がなく、Django側が静的ファイルの配信をします。 なので、DEBUG = Trueの状態ではDjango側が配信するように設定されます。
しかしデプロイなど実際の本番環境中ではNginxなど静的ファイルの配信に最適化されたWebサーバーに静的ファイルをまとめて渡してしまいます。
このように実際には静的ファイルの配信はDjangoのお仕事ではないため、少し設定が必要になっちゃいます。(ある程度はDjango側がよしなにやってくれるので意外とやることはないです。) より詳しい話はDjango公式ドキュメントを見てみてください!
静的ファイル (画像、JavaScript、CSS など) を管理する
Django公式ドキュメント
📚 参考資料
静的ファイル (画像、JavaScript、CSS など) を管理する
Django公式ドキュメント