静的ファイルの公開方法

revision-up-to:17812 (1.4)
Django 1.3 で新たに登場しました: リリースノートを参照してください

Django の開発者は、ビューや、リクエストごとに新しくレンダリングされるテンプ レートといった、 Web アプリケーションの動的な部分にもっぱら関心を持っていま す。しかし、 Web アプリケーションには静的なファイル ( 画像、CSS、JavaScriptな ど ) も含まれています。完全な Web ページをレンダリングするためにはこういった ファイルが必要です。

小さなプロジェクトではこのことは大きな問題になりません。 Web サーバが見つけら れる場所で静的ファイルを単に管理することができるからです。しかし、もっと大きな プロジェクトで、特に複数のアプリケーションからなる場合は、各アプリケーションが 持っている静的ファイルの集まりを複数扱うことになり、ややこしくなってきます。

django.contrib.staticfiles はまさにそのためにあります。これは静的なファイ ルを各アプリケーションから (さらに指定した別の場所からも) 一つの場所に集め、運 用環境で公開しやすくするものです。

Note

もし django-staticfiles アプリケーションを使ったことがあるなら、 django.contrib.staticfiles はよく似たものに見えるでしょう。それはこの 2 つが本質的に同じコードだからです。 django.contrib.staticfilesdjango-staticfiles として生まれ、 Django 1.3 に取り込まれました。

django.contrib.staticfiles を使う

基本的な使い方

  1. staticfiles が見つけられる場所に静的ファイルを置いてください。

    デフォルトでは、 INSTALLED_APPS に入っているアプリケーションの static/ サブディレクトリです。

    おそらく、あなたのプロジェクトには特定のアプリケーションに結びついていない 静的なファイルもあるでしょう。 STATICFILES_DIRS には、静的ファイ ルをロードする時にチェックすべきファイルシステム上のディレクトリを、タプル で記述します。

    staticfiles がファイルを探す方法の詳細について知るには STATICFILES_FINDERS 設定のドキュメントを参照してください。

  2. INSTALLED_APPSdjango.contrib.staticfiles が入っているこ とを確認してください。

    ローカル環境での開発runserver を使っているか、 staticfiles_urlpatterns を URLconf に追加し てあるなら、これでセットアップは終わりです。 自動的に STATIC_URL で静的ファイルが公開されます。 ( newly created プロジェクトでは ) デフォルト設定が /static/ です。

  3. きっとこれらのファイルをテンプレートで使いたいでしょう。一番簡単な方法は コンテキストプロセッサを使うことです。次のようなテンプレートを書けます:

    <img src="{{ STATIC_URL }}images/hi.jpg" />
    

    もっと詳しいことは staticfiles-in-templates に書いてあります。テンプ レートタグを使う別の方法も 書かれています

ごく簡単に、静的ファイルのデプロイについて

ローカル環境での開発が終わり、プロジェクトをデプロイする準備ができたら:

  1. STATIC_URL を静的なファイルを指すパブリックな URL に設定してくだ さい。 ( ほとんどの場合、デフォルト値である /static/ でうまく行きます )

  2. STATIC_ROOT に、 collectstatic コマンドを使って静的な ファイルを集めたいファイルシステム上のパスを設定してください。例えば:

    STATIC_ROOT = "/home/jacob/projects/mysite.com/sitestatic"
    
  3. collectstatic コマンドを実行してください:

    ./manage.py collectstatic
    

    このコマンドは静的ファイルのストレージを漁って、見つけたファイルを STATIC_ROOT で与えられたディレクトリにコピーします。

  4. STATIC_ROOT に含まれるファイルが STATIC_URL の場所で 公開されるように Web サーバを設定しデプロイしてください。

    staticfiles-production はいくつかのよくある静的ファイルのデプロイ手 法に言及しています。

これらは 基本 です。設定オプションについてもっと深く知るには、さらに読むべ きものがあります。設定やコマンド、またフレームワークに含まれる他のちょっとした ことを知るために、 staticfiles リファレンス を参照してください。

Note

Django の以前のバージョンでは、ユーザがアップロードしたファイルを置くための MEDIA_ROOT に静的なファイルも一緒に置かれ、どちらも MEDIA_URL で公開されていました。 staticfiles アプリケーショ ンを使う目的の 1 つは、静的ファイルとユーザがアップロードしたファイルとを分 けて管理することを簡単にするためです。

この理由から、 MEDIA_ROOT および MEDIA_URLSTATIC_ROOT および STATIC_URL とは別の値にしなければ なりません。 MEDIA_ROOT に含まれるファイルを公開するには、自分で 整理する必要があります。 staticfiles はユーザがアップロードしたファイル を全く扱わないのです。ただし、 MEDIA_ROOT のファイルを公開するた めに django.views.static.serve() ビューを使うことはできます。 staticfiles-other-directories を参照してください。

テンプレートから静的なファイルを参照する

テンプレートではいくつかの箇所で静的なファイルをリンクする必要があるでしょう。 もちろん、テンプレートで静的ファイルを単にハードコードすることは可能です:

<img src="http://static.example.com/static/myimage.jpg" />

当然ながら、これでは深刻な問題がいくつかあります。開発環境ではうごきませんし、 静的ファイルを公開する場所を変更するのが 非常に 困難です。例えばもし、 コン テンツデリバリーネットワーク (CDN) を使うように切り替えたい場合、テンプレート 全てを一つ一つ変更することになってしまいます。

もっと良い方法は STATIC_URL の値を直接テンプレートで使うことです。 こうすると、一つの値を変更するだけで静的ファイルのサーバを切り替えることができ ます。ずっと良いですね!

Django にはこの設定値をテンプレートで使うための複数の方法があります。コンテキ ストプロセッサとテンプレートタグです。

コンテキストプロセッサを使う

組み込みのコンテキストプロセッサは簡単に使えます。 TEMPLATE_CONTEXT_PROCESSORS 設定に 'django.core.context_processors.static' が含まれていれば良いだけです。そし てデフォルトではそのようになっています。自ら設定を編集する場合は、こんな風にな るでしょう:

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
)

これができれば STATIC_URL をテンプレートで参照できます:

<img src="{{ STATIC_URL }}images/hi.jpg" />

{{ STATIC_URL }} がテンプレートが使えなければ、おそらくテンプレートのレン ダリングに RequestContext を使っていないためです。

手短に復習すると、コンテキストプロセッサは全てのテンプレートのコンテキストに変 数を追加します。しかし、コンテキストプロセッサはテンプレートのレンダリングに RequestContext を使うことを要求します。 generic view を使えば自動的にそうなりますが、 自作のビューでは明示的に RequestContext を使わなければなりません。 これがどのように動くか知りたければ、 コンテキストのサブクラス: RequestContext をチェックしてください。

別の方法は Django 本体に含まれる get_static_prefix テンプレートタグを 使うことです。

テンプレートタグを使う

よりパワフルなツールが static テンプレートタグで す。このタグは与えられた相対パスに対して、 STATICFILES_STORAGE スト レージの設定を使って URL を組み立てます。

{% load staticfiles %}
<img src="{% static "images/hi.jpg" %}" />

通常のコンテキスト変数を受け取ることもできます。例えば user_stylesheet 変 数がテンプレートに渡されたとすると:

{% load staticfiles %}
<link rel="stylesheet" href="{% static user_stylesheet %}" type="text/css" media="screen" />

Note

Django コアセットの ビルトインテンプレートタグ に含まれる static テンプレートタグもあります。これは同じ引数を持ちますが、 STATIC_URL 設定と与えられたパスを単に urlparse.urljoin() に 渡します。これはテンプレートを変更することなく簡単にストレージバックエンド を切り替えることができないという不利な点があります。ですので注意して staticfilesstatic テンプレートタグを使 いましょう。

開発中の静的ファイルの扱い方

このツールは基本的に、運用環境にうまく静的ファイルをデプロイするのを補助するた めに設計されています。これは普通、別途専用で用意された静的ファイルサーバのこと ですが、ローカルでの開発時に使うには大きなオーバーヘッドがかかります。そこで staticfiles アプリは 手軽でダーティなヘルパービュー を導入します。これ によって開発中にローカルのファイルを使えるようになります。

ヘルパービューは自動で有効になっています。 runserver コマンドを使った時に STATIC_URL で静的ファイルを公開できます。

ローカル開発で他のサーバを使っている場合、このビューを有効にするには URLconf に 2 行追加する必要があります。 1 つめの行はファイルの先頭に、 2 つめ の行は末尾に書きます:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# ... URLconf の他の行がここに入ります

urlpatterns += staticfiles_urlpatterns()

この関数は STATIC_URL 設定を調べ、静的ファイルを適切に公開できるよ うにビューを設定します。アプリケーションディレクトリの中でどこを探せばいいかを django.contrib.staticfiles に教えるために、 STATICFILES_DIRS を 設定するのを忘れないでください。

Warning

ローカル環境でのファイル公開は DEBUGTrue の時にだけ動作 します。

それはこのビューが ひどく非効率 で、おそらく セキュアでない ためで す。このビューはローカル環境での開発だけを意図しており、 決して運用環境 で使うべきではありません

加えて、 staticfiles_urlpatterns を使うと、 STATIC_URL 設定は空であったり http://static.example.com/ 完 全な URL であったりできなくなります。

開発中の staticfiles の使い方についてもっと詳しく知るには staticfiles-development-view を参照してください。

他のディレクトリを公開する

serve(request, path, document_root, show_indexes=False)

プロジェクト内に含まれているものとは別のファイルもあるかもしれません。利便性の ため、ローカル環境での開発で Django に公開させたいのではないでしょうか。 serve() ビューは指定したどんなディレクトリも公開で きます。 (繰り返しますが、このビューは運用には耐えません。開発の補助としてだけ 使ってください。運用環境ではこれらのファイルは実際のフロントエンドサーバで公開 すべきです)

よくある例は MEDIA_ROOT にユーザがアップロードしたコンテンツです。 staticfiles は静的アセットを意図していて、ユーザがアップロードしたファイル のハンドリングは含まれていませんが、 URLconf に以下のような記述を追加すること で MEDIA_ROOT を Django に公開させることができます:

from django.conf import settings

# ... URLconf の他の部分がここに入ります ...

if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),
   )

このスニペットは MEDIA_URL'/media/' という値になっているこ とを仮定しています。 serve() を呼び出し、 URLconf と ( 必須の ) document_root パラメータをパスに渡します。

static(prefix, view='django.views.static.serve', **kwargs)

この URL パターンを定義するのはいささか大変になってくるので、 Django は小さな URL ヘルパー関数 static() を持っています。 これは MEDIA_URL のようなプレフィックスと、 'django.views.static.serve' のようなドット区切りのビューへのパスをパラメー タにとります。他の関数パラメータは透過的にビューに渡されます。

開発中に MEDIA_URL ('/media/') を公開する例です:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Note

このヘルパー関数は、デバッグモードの中で、与えられたプレフィックスが ( 例 /static/) ローカルであって URL ( 例 http://static.example.com/) ではない時にだけ操作できます。

運用環境での静的ファイル公開

運用環境に静的ファイルを置くための基本原則はシンプルです。静的ファイルが変 更された時には collectstatic コマンドを実行し、集められた静的ファイ ルのディレクトリ (STATIC_ROOT) を静的ファイルサーバに移動し、公開す るために整理します。

もちろん、あらゆるデプロイタスクと同様、細部には悪魔がいます。運用環境ごとに セットアップには小さな違いがあり、基本原則を必要に合うように変えなければならな いでしょう。以下はその助けになるかもしれないいくつかの共通パターンです。

一つのサーバでアプリケーションと静的ファイルを扱う

既にサイトを公開しているのと同じサーバで静的ファイルを公開したい場合、基本原則 は以下のように変更されます:

  • デプロイサーバにコードを展開します。
  • そのサーバ上で collectstatic を実行し、全ての静的ファイルを STATIC_ROOT 内にコピーします。
  • Web サーバに STATIC_ROOT を教えます。例えば Apache と mod_wsgi での方法 があります。

このプロセスはきっと自動化したくなるでしょう。特に複数の Web サーバを管理して いる時はそうです。この自動化を行う方法には色々ありますが、 Django を使う開発者 には嬉しいであろう一つの方法が Fabric です。

以下とそれに続くセクションでは、いくつかの fabfiles (Fabric scripts のこと ) を示します。それらはファイルのデプロイ方法を自動化してくれます。 fabfile の文 法はかなり直感的ですが、ここで網羅することはできません。 Fabric ドキュメント を読めば、文法の完全な説明が得られます。

静的ファイルを 2 つの Web サーバにデプロイする fabfile はこのようになるでしょ う:

from fabric.api import *

# デプロイ先のホスト
env.hosts = ['www1.example.com', 'www2.example.com']

# プロジェクトコードが格納される場所
env.project_root = '/home/www/myproject'

def deploy_static():
    with cd(env.project_root):
        run('./manage.py collectstatic -v0 --noinput')

専用のサーバで静的ファイルを公開する

大きな Django アプリケーションはたいてい別の Web サーバを静的ファイルの公開に 使っているでしょう。そのサーバでは Django は動いていません。 このサーバは別の種類の Web サーバ、速いがフル機能ではないものを使っていること が多いです。いくつか良い選択肢を挙げると:

これらのサーバの設定方法はこのドキュメントの範囲を超えますので、説明はそれぞれ のサーバの相当するドキュメントを調べてください。

静的ファイルサーバでは Django を動かせないでしょうから、デプロイ戦略を次のよう に変更する必要があります:

  • 静的ファイルが変更された時、 collectstatic をローカルで実行しま す。
  • ローカルの STATIC_ROOT を静的ファイルサーバの公開ディレクトリに アップロードします。 rsync は変更されたファイルのビットだけを転送するだ けで済むので、この手順の良い選択肢です。

fabfile はこのようになるでしょう:

from fabric.api import *
from fabric.contrib import project

# 静的ファイルがローカル環境で集められる場所
env.local_static_root = '/tmp/static'

# 静的ファイルがリモートで置かれる場所
env.remote_static_root = '/home/www/static.example.com'

@roles('static')
def deploy_static():
    local('./manage.py collectstatic')
    project.rysnc_project(
        remote_dir = env.remote_static_root,
        local_dir = env.local_static_root,
        delete = True
    )

クラウドサービスや CDN での静的ファイル公開

もう一つの一般的な手法は、静的ファイルを Amazon S3 のようなクラウドストレー ジプロバイダや、 CDN (content delivery network) で公開することです。これにより 静的ファイル公開の問題を気にせずにすみ、またしばしば (CDN を使う場合は特に ) Web ページを高速にロードさせることができます。

これらのサービスを使う場合、基本的なワークフローは上の話と少し似ていますが、 rsync を使ってファイルをサーバに転送する代わりに、ストレージプロバイダや CDN に送らなければならないところが違います。

これを行う方法は様々ですが、プロバイダに API がある場合、 カスタムファイルストレージバックエンド を 使えば、手順が信じられないほどシンプルになります。 STATICFILES_STORAGE に、自分が書いた、あるいはサードパーティ製のカ スタムストレージバックエンドを設定することにより、 collectstatic に そのバックエンドを使うように教えることができます。

例えば、 S3 ストレージバックエンドを myproject.storage.S3Storage に書いた とすると、このように使うことができます:

STATICFILES_STORAGE = 'myproject.storage.S3Storage'

こうすれば、 collectstatic をするだけで、静的ファイルはあなたのスト レージパッケージを経て S3 にアップロードされます。もし後で別のストレージプロバ イダに変更しなければならなくなっても、単に STATICFILES_STORAGE 設定 を変更するだけで済みます。

カスタムファイルストレージバックエンドを書く方法の詳細は カスタムのストレージシステムを作成する にあります。

See also

django-storages はサードパーティーアプリケーションで、 S3 を含む多 くな一般的なストレージ API のために、数多くのストレージバックエンドを提供 しています。

django-staticfiles からアップグレードする

django.contrib.staticfiles は元々 django-staticfiles として生まれまし た。もし django-staticfiles 1.0 以前 (0.3.4 など) から django.contrib.staticfiles にアップグレードしようとすると、いくつかの変更 をしなければなりません:

  • アプリケーションの静的ファイルはそれぞれのアプリケーションの static ディ レクトリになければなりません。 (django-staticfilesmedia という 少々混乱させる名前を使っていました)
  • コマンド build_staticresolve_static は今では collectstaticfindstatic という名前になっています。
  • 設定 STATICFILES_PREPEND_LABEL_APPS, STATICFILES_MEDIA_DIRNAMES, STATICFILES_EXCLUDED_APPS は削除されまし た。
  • 設定 STATICFILES_RESOLVERS は削除され、新しい STATICFILES_FINDERS に置き換えられました。
  • STATICFILES_STORAGE のデフォルトは staticfiles.storage.StaticFileStorage から staticfiles.storage.StaticFilesStorage にリネームされました。
  • ローカル環境で runserver を使う時 (DEBUG 設定が True の時) 、開発中の静的ファイル公開のために URLconf に何も追加する必要がなくなりました。

さらに学ぶためには

このドキュメントでは基本といくつかのよくある使用パターンについて説明しました。 django.contrib.staticfiles に含まれる全ての設定、コマンド、テンプレートタ グ、その他について、完全な詳細を知るには staticfiles リファレンス を参照してください。