staticfiles アプリ

django.contrib.staticfiles は、各アプリケーション(と、あらかじめ指定した他の場所)から静的ファイルを収集し、本番環境で簡単に提供できるように一か所にまとめます。

参考

静的ファイルアプリの導入と活用例については、 静的ファイル (画像、JavaScript、CSS など) を管理する を参照してください。静的ファイルのデプロイに関するガイドラインについては、 静的ファイルをデプロイする を参照してください。

設定

次の設定に関する詳細については、 静的ファイルの設定 を参照してください。

管理コマンド

django.contrib.staticfiles は3つの管理コマンドを提供します。

collectstatic

django-admin collectstatic

静的ファイルを STATIC_ROOT に収集します。

デフォルトでは、重複するファイル名はテンプレートの解決方法と同様に処理されます。すなわち、指定された場所のいずれかで最初に見つかったファイルが使用されます。どのファイルが反映されたかわからない場合は、 findstatic コマンドを使用して、どのファイルが適用されたかを確認できます。

その後、再度 collectstatic を実行すると、( STATIC_ROOT が空でない限り)収集元のファイルは、そのタイムスタンプが STATIC_ROOT にあるファイルのタイムスタンプよりも後の日時であるときのみコピーされます。そのため、 INSTALLED_APPS からアプリケーションを削除するときは、 collectstatic --clear を実行することで古い静的ファイルを削除すると良いでしょう。

ファイルの検索には、 有効化された検索システム が使用されます。デフォルトでは、 STATICFILES_DIRS で定義されたすべての場所と、 INSTALLED_APPS 設定で指定されたアプリケーションの 'static' ディレクトリを参照します。

collectstatic コマンドは、実行するたび STORAGES から staticfiles ストレージバックエンドの post_process() メソッドを呼び出し、この管理コマンドによって見つかったファイルパスのリストを返します。同時に、 collectstatic のすべてのコマンドラインオプションを受け取ります。このオプションは、デフォルトでは ManifestStaticFilesStorage に渡されます。

デフォルトでは、収集されたファイルは FILE_UPLOAD_PERMISSIONS から、収集されたディレクトリは FILE_UPLOAD_DIRECTORY_PERMISSIONS からアクセス許可を受け取ります。これらのファイルまたはディレクトリに異なるアクセス許可を設定したい場合は、静的ファイルストレージのクラス のいずれかをサブクラス化し、それぞれ file_permissions_mode および/または directory_permissions_mode パラメータを指定します。以下に例を示します。

from django.contrib.staticfiles import storage


class MyStaticFilesStorage(storage.StaticFilesStorage):
    def __init__(self, *args, **kwargs):
        kwargs["file_permissions_mode"] = 0o640
        kwargs["directory_permissions_mode"] = 0o760
        super().__init__(*args, **kwargs)

次に、 STORAGES 設定で staticfiles ストレージバックエンドを 'path.to.MyStaticFilesStorage' と指定してください。

この管理コマンドでよく使われるオプションをいくつか示します。

--noinput, --no-input

ユーザーにいかなる入力も要求せずに処理を実行します。

--ignore PATTERN, -i PATTERN

指定した glob スタイルのパターンに一致するファイル、ディレクトリ、またはパスからの収集を行わないようにします。対象外のパターンが複数ある場合は、その数だけ指定してください。また、パスを指定するとき、Windowsでも常にスラッシュを使用してください。

--dry-run, -n

ファイルシステムを変更すること以外の全てを行います。

--clear, -c

既存のファイルを削除してから、元のファイルをコピーまたはリンクします。

各ファイルをコピーする代わりに、シンボリックリンクを作成します。

--no-post-process

STORAGES に設定された staticfiles ストレージバックエンドの post_process() メソッドを呼び出さないようにします。

--no-default-ignore

一般的なプライベート glob スタイルのパターンである 'CVS''.*' および '*~' を収集対象外としないようにします。

すべてのオプションのリストは、次のコマンドを実行してコマンドのヘルプから参照してください。

$ python manage.py collectstatic --help
...\> py manage.py collectstatic --help

無視パターンリストをカスタマイズする

デフォルトの無視パターンリストは ['CVS', '.*', '*~'] ですが、これは collectstatic の呼び出しのたびに --ignore オプションを指定することなく、より永続的な方法でカスタマイズできます。以下のように、 ignore_patterns 属性をオーバーライドしたカスタムの AppConfig クラスを実装し、 INSTALLED_APPS 設定で 'django.contrib.staticfiles' をそのカスタムクラスのパスに置き換えてください。

from django.contrib.staticfiles.apps import StaticFilesConfig


class MyStaticFilesConfig(StaticFilesConfig):
    ignore_patterns = [...]  # your custom ignore list

findstatic

django-admin findstatic staticfile [staticfile ...]

有効な検索機能を使用して、1つ以上の相対パスを検索します。

例:

$ python manage.py findstatic css/base.css admin/js/core.js
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
  /home/polls.com/src/django/contrib/admin/media/js/core.js
...\> py manage.py findstatic css\base.css admin\js\core.js
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
  /home/polls.com/src/django/contrib/admin/media/js/core.js
findstatic --first

デフォルトでは、一致するすべてのファイルのパスが表示されます。最初に見つかったファイルの相対パスだけを返すには、 --first オプションを使用してください。

$ python manage.py findstatic css/base.css --first
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --first
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css

指定したパスに対して収集された静的ファイルが正確に表示されるので、デバッグの助けになります。

--verbosity フラグを 0 に設定することで、追加の出力を抑制し、パス名のみを取得できます。

$ python manage.py findstatic css/base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css

一方、 --verbosity フラグを2に設定することで、検索されたすべてのディレクトリを取得することもできます。

$ python manage.py findstatic css/base.css --verbosity 2
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Looking in the following locations:
  /home/special.polls.com/core/static
  /home/polls.com/core/static
  /some/other/path/static
...\> py manage.py findstatic css\base.css --verbosity 2
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Looking in the following locations:
  /home/special.polls.com/core/static
  /home/polls.com/core/static
  /some/other/path/static

runserver

django-admin runserver [addrport]

staticfiles アプリケーションが インストール されている場合、 runserver コマンドを上書きし、静的ファイルの自動サービスを追加します。ファイルのサービスは MIDDLEWARE を経由しません。

このコマンドには、以下のオプションが追加されています。

--nostatic

--nostatic オプションを使用すると、 staticfiles アプリケーションによる静的ファイルの配信を完全に無効にします。このオプションは、 INSTALLED_APPS 設定に staticfiles アプリケーションが含まれている場合にのみ利用可能です。

使用例:

$ django-admin runserver --nostatic
...\> django-admin runserver --nostatic
--insecure

--insecure オプションを使用すると、 DEBUG 設定が False の場合でも、静的ファイルを強制的に staticfiles アプリで配信します。これを使用する場合、 非常に非効率的 で、おそらく 安全ではない ことを受け入れる必要があります。これはローカル開発のみを目的としているので、 本番環境では使用しないでください 。また、 staticfiles アプリがプロジェクトの INSTALLED_APPS 設定に含まれている場合のみ利用可能です。

--insecure オプションは ManifestStaticFilesStorage と同時に使用することはできません。

使用例:

$ django-admin runserver --insecure
...\> django-admin runserver --insecure

ストレージ

StaticFilesStorage

class storage.StaticFilesStorage

FileSystemStorage ストレージバックエンドのサブクラスです。 STATIC_ROOT 設定を基本ファイルシステムの場所として、STATIC_URL 設定を基本URLとして使用します。

storage.StaticFilesStorage.post_process(paths, **options)

このメソッドがストレージ上で定義されている場合は、 collectstatic 管理コマンドが実行されるたびに呼び出され、見つかったファイルのローカルストレージとパス、およびコマンドラインオプションが辞書として渡されます。この処理は original_pathprocessed_pathprocessed の3つの値のタプルを生成します。パスの値は文字列であり、 processed は値が事後処理されたかどうかを示すブール値であり、事後処理が失敗した場合は例外が格納されます。

ManifestStaticFilesStorage は、これを裏で使用してパスをハッシュ化された対応するパスに置き換え、キャッシュを適切に更新します。

ManifestStaticFilesStorage

class storage.ManifestStaticFilesStorage

StaticFilesStorage のストレージバックエンドのサブクラスです。ファイル名を処理する際に、ファイルの内容のMD5ハッシュをファイル名に追加して保存します。たとえば、ファイル css/styles.csscss/styles.55e7cbb9ba48.css として保存されます。

このストレージの目的は、古いファイルを提供し続けることです。なぜなら、古いファイルはあなたや第三者のプロキシサーバによってキャッシュされており、いくつかのページがまだそれらのファイルを参照することがあるからです。また、展開されたファイルに far future Expires headers を適用して、次回のページ訪問の読み込み時間を高速化する場合にも非常に役立ちます。

保存されたファイル内のパスが他の保存されたファイルと一致する場合、ストレージバックエンドは自動的にキャッシュされたコピーのパスでそれらのパスを置き換えます(このとき、 post_process() メソッドを使用)。これらのパスを検索するために使用される正規表現( django.contrib.staticfiles.storage.HashedFilesMixin.patterns )は以下に対応しています。

ManifestStaticFilesStorage のサブクラスを作成し、 support_js_module_import_aggregation 属性を True に設定すると、実験的な正規表現を使用して以下にも対応できます。

たとえば、以下のような 'css/styles.css' を定義します。

@import url("../admin/css/base.css");

...これは ManifestStaticFilesStorage ストレージバックエンドの url() メソッドを呼び出すことで置換され、最終的に 'css/styles.55e7cbb9ba48.css' というファイルが以下の内容で保存されます。

@import url("../admin/css/base.27e20196a850.css");

ローカルファイルに対する integrity HTML属性の使用方法

<script><link> のようなタグ内で任意の integrity 属性を使用する場合、その値はファイルシステムに保存されている状態ではなく、提供されるファイルに基づいて計算されるべきです。これは、静的ファイルがどのように収集されるかによって、そのチェックサムが変更され得るため、特に重要です(例えば、collectstatic を使用した場合)。現時点では、このための既製のツールは用意されていません。

マニフェストファイルの場所は、manifest_storage 引数を設定するカスタムの ManifestStaticFilesStorage サブクラスを使用することで変更できます。たとえば:

from django.conf import settings
from django.contrib.staticfiles.storage import (
    ManifestStaticFilesStorage,
    StaticFilesStorage,
)


class MyManifestStaticFilesStorage(ManifestStaticFilesStorage):
    def __init__(self, *args, **kwargs):
        manifest_storage = StaticFilesStorage(location=settings.BASE_DIR)
        super().__init__(*args, manifest_storage=manifest_storage, **kwargs)

コメント内の参照

ManifestStaticFilesStorage は、コメントアウトされた文内のパスを無視しません。これにより、存在しないパスで クラッシュする可能性があります 。コメントをチェックし、必要に応じて削除するべきです。

storage.ManifestStaticFilesStorage.manifest_hash

この属性は、マニフェスト内のファイルが変更されるたびに変わる単一のハッシュを提供します。これは、サーバー上のアセットが変更されたこと(新しいデプロイメントが原因)をSPAに通知するのに役立つことがあります。

storage.ManifestStaticFilesStorage.max_post_process_passes

静的ファイルは他の静的ファイルを参照することがあるため、パスを置き換える処理を複数回行う必要があります。ファイルのハッシュが収束するまでこの処理を繰り返します。無限ループを防ぐため('foo.css''bar.css' を参照し、その 'bar.css' が再び 'foo.css' を参照する例のように、ハッシュが収束しない場合)、ポストプロセッシングを中止する前に最大で何回のパスが可能かを設定しています。多くの参照があるケースでは、より多くのパスが必要になることがあります。最大パス数を増やすには、ManifestStaticFilesStorage をサブクラス化し、max_post_process_passes 属性を設定します。デフォルトは5です。

ManifestStaticFilesStorage を有効にするには、以下の要件を満たしていることを確認してください:

  • STORAGES 設定の staticfiles ストレージバックエンドが 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage' に設定されていること
  • DEBUG 設定が False に設定されていること
  • collectstatic 管理コマンドを使用して、全ての静的ファイルを収集したこと

MD5ハッシュを作成することは、実行時にウェブサイトにとってパフォーマンス上の負担となる可能性があるため、 staticfiles は自動的に staticfiles.json というファイルに、処理されたすべてのファイルのハッシュ名とマッピングを保存します。これは collectstatic 管理コマンドを実行したときに一度だけ起こります。

storage.ManifestStaticFilesStorage.manifest_strict

実行時に staticfiles.json マニフェストでファイルが見つからない場合、ValueError が発生します。この動作は、ManifestStaticFilesStorage をサブクラス化し、manifest_strict 属性を False に設定することで無効にできます(存在しないパスはそのままになります)。

collectstatic を実行する必要があるため、このストレージは通常、テストの実行時には使用しないでください。テスト中は、 STORAGES 設定にある staticfiles ストレージバックエンドが 'django.contrib.staticfiles.storage.StaticFilesStorage' (デフォルト) のように他のものに設定されていることを確認してください。

storage.ManifestStaticFilesStorage.file_hash(name, content=None)

ファイルのハッシュ化された名前を作成する際に使用されるメソッドです。与えられたファイル名と内容に対するハッシュを返す必要があります。デフォルトでは、上述のように、内容のチャンクからMD5ハッシュを計算します。このメソッドをオーバーライドして、独自のハッシュアルゴリズムを使用することもできます。

ManifestFilesMixin

class storage.ManifestFilesMixin

カスタムストレージでこのミックスインを使用すると、 ManifestStaticFilesStorage が行うように、ファイルの内容の MD5 ハッシュをファイル名に追加します。

ファインダー・モジュール

staticfiles ファインダーには、ファインダーが検索したディレクトリパスのリストである searched_locations 属性があります。使用例:

from django.contrib.staticfiles import finders

result = finders.find("css/base.css")
searched_locations = finders.searched_locations

その他のヘルパー

staticfiles アプリ以外にも、静的ファイルを扱うためのいくつかの他のヘルパーがあります。

  • django.template.context_processors.static() コンテキストプロセッサは、 RequestContext コンテキストでレンダリングされたすべてのテンプレートコンテキストに STATIC_URL を追加します。
  • 組み込みのテンプレートタグ static はパスを受け取り、静的なプレフィックス STATIC_URL と urljoin します。もし django.contrib.staticfiles がインストールされていれば、代わりに STORAGES にある staticfiles ストレージバックエンドの url() メソッドを使用します。
  • 組み込みのテンプレートタグ get_static_prefix は、テンプレート変数に静的プレフィックス STATIC_URL を代入し、変数として、または直接使用します。
  • 同様のテンプレートタグ get_media_prefixget_static_prefix のように動作しますが、 MEDIA_URL を使用します。
  • staticfiles キーは django.core.files.storage.storages に含まれており、 staticfiles ストレージバックエンドの使用準備が整ったインスタンスが格納されています。

静的ファイル開発ビュー

静的ファイルツールは、主に静的ファイルを本番環境にうまくデプロイするために設計されています。これは通常、開発時には扱いが大変な専用の静的ファイルサーバーを意味します。そのため、staticfiles アプリには、開発中にローカルでファイルを提供するために使用できる 素早くて簡易なヘルパービュー が同梱されています。

views.serve(request, path)

このビュー関数は、開発中に静的ファイルを配信します。

警告

このビューは DEBUGTrue の場合にのみ機能します。

このビューは 極めて非効率的 であり、おそらく セキュリティ上の問題 も抱えています。このビューは、 ローカル開発向け であり、 本番環境で使用するべきではありません

注釈

提供するファイルのコンテンツタイプを推測するために、このビューはPython標準ライブラリの mimetypes モジュールに依存しています。これは、その下層にあるプラットフォームのマップファイルにも依存しています。もし、このビューが特定のファイルに対して適切なコンテンツタイプを返さない場合、最も可能性が高いのは、プラットフォームのマップファイルが不正確であるか、更新が必要であることを意味しています。例えば、Red Hatディストリビューションで mailcap パッケージをインストールまたは更新すること、Debianディストリビューションで mime-support をインストールまたは更新すること、あるいはWindowsレジストリの HKEY_CLASSES_ROOT 下のキーを編集することによって、これを修正できます。

このビューは、 runserver (および DEBUG 設定が True に設定されている場合) によって自動的に有効になります。異なるローカル開発サーバーでこのビューを使用するには、主要なURL設定の末尾に以下のコードを追加してください:

from django.conf import settings
from django.contrib.staticfiles import views
from django.urls import re_path

if settings.DEBUG:
    urlpatterns += [
        re_path(r"^static/(?P<path>.*)$", views.serve),
    ]

注意: パターンの先頭 (r'^static/') はあなたの設定 (STATIC_URL) であるべきです。

これは少し厄介なので、これを代行してくれるヘルパー関数もあります:

urls.staticfiles_urlpatterns()

これは、すでに定義されているパターンリストに静的ファイルを提供するための適切なURLパターンを返します。次のように使います:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# ... the rest of your URLconf here ...

urlpatterns += staticfiles_urlpatterns()

これにより、STATIC_URL 設定が検査され、静的ファイルを適切に提供するためのビューが設定されます。 django.contrib.staticfiles がアプリディレクトリ内のファイルに加えて、どこでファイルを探せばよいかを知るために、 STATICFILES_DIRS 設定を適切に設定することを忘れないでください。

警告

このヘルパー関数は、 DEBUGTrue であり、かつ STATIC_URL の設定が空でも完全なURL (例: http://static.example.com/) でもない場合にのみ動作します。

このビューは 極めて非効率的 であり、おそらく セキュリティ上の問題 も抱えています。このビューは、 ローカル開発向け であり、 本番環境で使用するべきではありません

「ライブテスト」をサポートするための特別なテストケース

class testing.StaticLiveServerTestCase

この unittest の TestCase サブクラスは django.test.LiveServerTestCase を拡張しています。

親と同様に、テスト対象のコードを実行し、HTTP を介してテストツール(例: Selenium、PhantomJS など)で使用するテストを記述するために使用できます。そのため、静的アセットも公開する必要があります。

しかし、上記で説明した django.contrib.staticfiles.views.serve() ビューを利用しているため、テスト実行時に staticfiles ファインダーによって配信されたアセットを透過的に上書きできます。つまり、テストのセットアップの前やその一部として collectstatic を実行する必要はありません。

Back to Top