※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part12)〜get_absolute_url()~
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part14)〜ページのデザイン~

【初心者チュートリアル】Django2でブログ作成(Part13)〜collectstatic~

web開発 python3 Django python Djangoチュートリアル collectstatic

投稿日:2019年11月26日

このエントリーをはてなブックマークに追加
Djangoは簡単にWebアプリケーションを作成できるフレームワークです。この記事は初心者の方向けのDjangoチュートリアルです。

はじめに

この記事について

ここまでの記事で基本的なブログの機能については実装できました。しかし、サイトを見てみると白いページに黒い文字がならんでるだけでなんだか寂しいですね。
ここからのPartではCSSでの簡単なデザインをしていきます。
そして今回の記事はそのスタートとしてDjangoの静的ファイル管理ツールcollectstaticについてその簡単なと必要な設定について書いていきます。


collectstatic

collectstaticとは?

Djangoでは静的ファイルをmanage.pycollectstaticというコマンドで管理します。このコマンドは全てのアプリケーションのディレクトリの静的ファイルを一つにまとめる機能を持ちます。これによってサードパーティのアプリケーション(他の誰かが作ったライブラリ)をプロジェクトにインストールしたときにも、collectstaticがまとめたディレクトリだけを公開すれば必要な全ての静的ファイルが公開できるわけです。
実際のプロジェクトを開発する際にはcollectstaticを使う流れは下の様になるでしょう。

  1. 静的ファイル(cssやjsなど)でそれぞれのアプリケーションをデザインする
  2. collectstaticで自分の静的ファイルとサードパーティの静的ファイルを一つのディレクトリにまとめる
  3. webサーバー(nginxApache)で、collectstaticまとめたディレクトリを静的ファイルとして公開する

collectstaticの問題点

collectstaticは全てのアプリケーションのディレクトリの静的ファイルを探しにいくため、静的ファイルはアプリケーションのどれかのディレクトリにはいっている必要があります。
しかし、開発する上で静的ファイルがあちらこちらに散らばるのは個人的に少し使いづらく感じます(templateについても同様)。静的ファイルでは基本的な開発は決まった一つのディレクトリで行い、プロジェクトの規模が大きくなったりアプリケーションを再利用・またはパッケージとして公開するときに、はじめてアプリケーションごとに分割するのが良いでしょう。
今回はcollectstaticの設定を少しだけカスタマイズして静的ファイルのディレクトリをひとつにまとめられるようにします。この開発方法はあくまで僕個人が開発しやすいと感じるものなので、この管理方法にとらわれず好きな管理方法で開発してください。

collectstaticの基本設定

collectstaticは以下の様なルールでファイルを一つの場所にまとめます。

  • このコマンドによって静的ファイルをまとめる先はSTATIC_ROOTの設定で指定された絶対パス
  • コマンドで検索されるディレクトリはINSTALLED_APPSに入ったアプリケーションのディレクトリのstaticディレクトリの中と、STATICFILES_DIRSで指定した場所です。

デフォルトではSTATIC_ROOTは設定されていないため必ずここの設定はする必要があります。そのままcollectstaticをしようとすると以下の様にエラーが出力されます。

ターミナル
$ python manage.py collectstatic
[...]
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.

例えば特に何も考えずプロジェクトルートの直下でstaticという名前のディレクトリで管理する場合には以下の様な設定になるでしょう。

sample_blog/sample_blog/settings.py
[...]

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

[...]

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

この状態でblogアプリケーションに新しくstaticディレクトリを作ってみましょう。アプリケーションごとに静的ファイルを管理する場合には、慣習として更にその中にアプリケーション名のディレクトリを作成し、その中でそれぞれjscssを管理します。

ディレクトリ構造
sample_blog/blog/static/
└── blog/
    ├── css/
    │   └── sample.css   # 空ファイル
    └── js/
        └── sample.js     # 空ファイル

この状態でcollectstaticをすると

ディレクトリ構造
sample_blog/static/
├── admin
│   ├── css
│   ├── fonts
│   ├── img
│   └── js
└── blog
    ├── css
    │   └── sample.css
    └── js
        └── sample.js

この様にアプリケーションのstaticディレクトリの中身がSTATIC_ROOTで指定したディレクトリにあつまりました。

アプリケーションの静的ファイルをまとめて管理する場合

もちろんDjangoの推奨するアプリケーションごとの静的ファイルの管理は、ソースの再利用という思想の基には非常に良い設計だと思います。
しかし、cssファイルやjsファイルがいろんなディレクトリに別れどこにあるかひと目でわからないプロジェクトでは、実際に開発する段階でどうなるでしょう?例えばデザイナーはいろんなディレクトリを行ったり来たりし、またプロジェクト管理者もどのディレクトリを誰が管理すれば良いのかばかりに気を取られてしまうかもしれません。
そこで僕が行っている管理方法では、プロジェクト全体の静的ファイルを一つのディレクトリにまとめて管理します。このためにはSTATICFILES_DIRSの設定を追加して上げればOKです。
今回はプロジェクトディレクトリの中にstaticディレクトリを作りそこでプロジェクト全体の静的ファイルを管理することにします。

sample_blog/sample_blog
[...]
STATICFILES_DIRS = [
    ("", os.path.join(BASE_DIR, "sample_blog/static")),
]

それとurlの設定を追加してあげましょう。

sample_blog/sample_blog/urls.py
from django.urls import path, include
from django.contrib import admin

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

# 以下が追加部分

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings

if settings.DEBUG:
    urlpatterns += staticfiles_urlpatterns()

このurlの設定は開発中のデバッグに必須のものになります。基本コピペでOKです。
では実際にまとめましょう。と、その前にはじめ作成したblogstaticディレクトリはもう使わないので削除しておいてください。
プロジェクトディレクトリに新たにstaticディレクトリを作成し以下のような構成にします。

ディレクトリ構造
sample_blog/sample_blog/static/
├── css/
│   └── sample.css   # サンプルの空ファイル
├── js/
│   └── sample.js      # サンプルの空ファイル

あとはcollectstaticコマンドをうってあげましょう。

ターミナル
$ rm -r -f blog/static
$ python manage.py collectstatic --clear

collectstatic--clearオプションはSTATIC_ROOTのディレクトリの中を一端空にしてもう一度いちから集め直すというオプションです。設定を変えた後など、staticディレクトリにゴミファイルを残したくない場合にはこのオプションをつけましょう。

以下の様に静的ファイルをまとめる事ができます。

まとめられた静的ファイル
sample_blog/static/
├── admin/
│   ├── css/
│   ├── fonts/
│   ├── img/
│   └── js/
├── blog/
│   ├── css/
│   └── js/
├── css/
│   └── sample.css
└── js/
    └── sample.js

やってはいけないこと

開発が進んでサーバーにデプロイした後はcollectstaticであつめられた静的ファイルのディレクトリ(STATIC_ROOT)がそのまま公開されると思います。その場合静的ファイルの内容を変更しようとしたときには注意が必要です。ファイルの配信の設定をみてSTATIC_ROOTのディレクトリに静的ファイルのオリジナルがあると勘違いしてしまう人が出てくることがあるのです。
その勘違いのまま静的ファイルの内容を変更するとおそらく、STATIC_ROOTの中身に編集を加えてしまうでしょう。しかし、実際にこのディレクトリはcollectstaticによって本来の静的ファイルがコピーされてまとめられたディレクトリでしかありません。
そこを編集しても次collectstaticコマンドが実行されたときにオリジナルに上書きされてしまうのです。
つまり僕が言いたいのは...
静的ファイルの実体がどこにあるかはプロジェクトのメンバーに必ず共有しましょう!!


さいごに

まとめ

  • 静的ファイルをまとめるためにはcollectstaticコマンドを使いましょう
  • collectstaticコマンドはSTATIC_ROOTで指定した先にファイルを集めます
  • collectstaticコマンドで別のディレクトリを探索させたいときにはSTATICFILE_DIRSの設定とurls.pyをカスタマイズしましょう。
このエントリーをはてなブックマークに追加

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part12)〜get_absolute_url()~
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part14)〜ページのデザイン~

関連記事

記事へのコメント