.. _ref-templates-api: ======================================================= Python プログラマのための Django テンプレート言語ガイド ======================================================= :revision-up-to: 11321 (1.1) unfinished このドキュメントでは、 Django のテンプレートシステムを技術的な側面、すなわ ちどのように動作し、どうやって拡張するかという観点から解説します。テンプレー ト言語の構文リファレンスを探しているのなら、 :doc:`/topics/templates` を参照 してください。 Django テンプレートシステムを他のアプリケーションの部品として使いたい場合、 すなわち Django フレームワークの他の部分は必要ない場合、このドキュメントの 後の方にある `設定 <#ref-templates-configuring-standalone>`_ の節に必ず目を 通して下さい。 基礎 ==== **テンプレート (template)** とは、 Django テンプレート言語を使ってマークアッ プしたテキストドキュメントや Python 文字列です。テンプレートには **ブロックタグ (block tag)** や **変数 (variable)** を入れられます。 **ブロックタグ** はテンプレート中で何らかの処理を行う部分を表すシンボルです。 とはいえ、この定義はいささか曖昧ですね。例えば、ブロックタグを使うと、何ら かのコンテンツを出力したり、制御構造 ("if" 文や "for" ループ) を記述したり、 データベースからコンテンツを取り出したり、他のテンプレートタグにアクセスし たりします。 ブロックタグは ``"{%"`` と ``"%}"`` で囲みます。 ブロックタグを使ったテンプレートの例を示します: .. code-block:: html+django {% if is_logged_in %}Thanks for logging in!{% else %}Please log in.{% endif %} **変数** はテンプレート中で何らかの値を出力する部分を表すシンボルです。 変数は ``"{{"`` と ``"}}"`` で囲みます。 変数を使ったテンプレートの例を示します。: .. code-block:: html+django My first name is {{ first_name }}. My last name is {{ last_name }}. **コンテキスト (context)** はテンプレートに渡される「変数名」から「変数の値」 へのマッピングです。 テンプレートの **レンダリング (rendering)** では、コンテキストから値を取り 出して変数という「穴」に埋め、全てのブロックタグを実行します。 テンプレートシステムの利用 ========================== .. class:: django.template.Template Python でテンプレートを使うには、以下の 2 段階のプロセスを踏みます: * 生のテンプレートをコンパイルして ``Template`` オブジェクトを生成しま す。 * コンテキストを指定して、 ``Template`` オブジェクトの ``render()`` メ ソッドを呼び出します。 文字列のコンパイル ------------------ ``Template`` オブジェクトを作成するには、直接インスタンスを生成する方法が最 も簡単です。 ``Template`` クラスは :class:`django.template.Template` にあります。 コンストラクタは引数に生のテンプレートコードを取ります:: >>> from django.template import Template >>> t = Template("My name is {{ my_name }}.") >>> print t .. admonition:: 舞台裏 :class: admonition-behind-the-scenes このシステムは ``Template`` オブジェクトを生成するときに生のテンプレー トコードを一度しか解析しません。コンパイル後のテンプレートはパフォーマ ンス上の目的から "node" データ構造に保存されます。 テンプレートコードの解析自体もきわめて高速です。解析のほとんどは短い正 規表現を一つ呼び出すだけで終わります。 コンテキストのレンダリング -------------------------- .. method:: render(context) コンパイル済みの ``Template`` オブジェクトを作成したら、オブジェクトを使っ てコンテキストをレンダリングできるようになります。 ``Context`` クラスは :class:`django.template.Context` にあります。コンテキストクラスのコンストラクタ は二つの (省略可能な) 引数をとります: .. * A dictionary mapping variable names to variable values. .. * The name of the current application. This application name is used to help :ref:`resolve namespaced URLs`. If you're not using namespaced URLs, you can ignore this argument. * 変数名と変数値を対応づける辞書 * 現在のアプリケーション名。このアプリケーション名は :ref:`名前空間による URL の解決` で役立ちます。もし名前空間化 された URL を使用していなければ、この引数は無視して問題ありません。 ``Template`` オブジェクトの ``render()`` メソッドを呼び出すと、コンテキス トの値でテンプレートを「埋め」て出力します:: >>> from django.template import Context, Template >>> t = Template("My name is {{ my_name }}.") >>> c = Context({"my_name": "Adrian"}) >>> t.render(c) "My name is Adrian." >>> c = Context({"my_name": "Dolores"}) >>> t.render(c) "My name is Dolores." .. Variable names must consist of any letter (A-Z), any digit (0-9), an underscore (but they must not start with an underscore) or a dot. 変数名には、任意の文字 (A-Z)、数字 (0-9)、アンダースコアまたはドットしか 使えません (ただしアンダースコアで始めてはいけません)。 ドットはテンプレートレンダリングにおいて特殊な意味を持ちます。変数名中の ドットは、 **値の照合 (lookup)** を意味します。もっと詳しく言えば、テンプレー トシステムが変数名中にドットを見つけた場合、以下の順で値の照合を試みます: * ``foo["bar"]`` のような辞書としての照合。 * ``foo.bar`` のような属性値の照合。 * ``foo[bar]`` のようなリストのインデクス指定。 テンプレートシステムは最初に成功した照合結果を使います。いわば短絡的ロジッ ク (short-circuit logic) です。いくつか例を示します:: >>> from django.template import Context, Template >>> t = Template("My name is {{ person.first_name }}.") >>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}} >>> t.render(Context(d)) "My name is Joe." >>> class PersonClass: pass >>> p = PersonClass() >>> p.first_name = "Ron" >>> p.last_name = "Nasty" >>> t.render(Context({"person": p})) "My name is Ron." >>> t = Template("The first stooge in the list is {{ stooges.0 }}.") >>> c = Context({"stooges": ["Larry", "Curly", "Moe"]}) >>> t.render(c) "The first stooge in the list is Larry." .. If any part of the variable is callable, the template system will try calling it. Example:: もし変数 (のいずれかの部分) が呼び出し可能オブジェクト (callable) である場合、 テンプレートシステムはそれを呼び出そうとします。たとえば:: >>> class PersonClass2: ... def name(self): ... return "Samantha" >>> t = Template("My name is {{ person.name }}.") >>> t.render(Context({"person": PersonClass2})) "My name is Samantha." .. .. versionchanged:: 1.3 Previously, only variables that originated with an attribute lookup would be called by the template system. This change was made for consistency across lookup types. .. versionchanged:: 1.3 以前は、呼び出し可能オブジェクトは「ある変数の属性として照合された場合 にだけ」テンプレートシステムから呼び出されていました。この仕様は、 照合方法に一貫性を持たせるために変更されました。 .. Callable variables are slightly more complex than variables which only require straight lookups. Here are some things to keep in mind: 呼び出し可能な変数の場合、ただ照会すれば良い普通の変数に比べるとちょっと 複雑になります。いくつか心に留めておくべきことを挙げておきます: .. If the variable raises an exception when called, the exception will be propagated, unless the exception has an attribute ``silent_variable_failure`` whose value is ``True``. If the exception *does* have a ``silent_variable_failure`` attribute whose value is ``True``, the variable will render as an empty string. Example:: * もし変数呼び出し時に例外が送出された場合、その例外に ``silent_variable_failure`` という属性があり、かつ値が ``True``に設 定されている場合を除き、例外はそのまま伝播します。例外が ``silent_variable_failure`` という属性を持つ場合、変数は空文字列にレ ンダリングされます。例えば:: >>> t = Template("My name is {{ person.first_name }}.") >>> class PersonClass3: ... def first_name(self): ... raise AssertionError, "foo" >>> p = PersonClass3() >>> t.render(Context({"person": p})) Traceback (most recent call last): ... AssertionError: foo >>> class SilentAssertionError(Exception): ... silent_variable_failure = True >>> class PersonClass4: ... def first_name(self): ... raise SilentAssertionError >>> p = PersonClass4() >>> t.render(Context({"person": p})) "My name is ." 全ての Django データベース API の ``DoesNotExist`` 例外の基底クラスで ある :exc:`django.core.exceptions.ObjectDoesNotExist` では ``silent_variable_failure = True`` になっているので注意してください。 つまり、 Django テンプレートと Django モデルオブジェクトを使っている 限り、 ``DoesNotExist`` 例外が出ても暗黙のうちに失敗するだけなのです。 .. * A variable can only be called if it has no required arguments. Otherwise, the system will return an empty string. * 呼び出し可能な変数は、指定必須の引数が無い場合にだけ呼び出されます。 指定必須の引数がある場合は、空の文字列になります。 .. * Obviously, there can be side effects when calling some variables, and it'd be either foolish or a security hole to allow the template system to access them. * 言うまでもないことですが、呼び出すと副作用を起こす変数もあります。 副作用のある変数にテンプレートからアクセスできるようにしておくと、 間抜けな結果になったりセキュリティホールを作ったりしてしまうことがある ので注意して下さい。 分かりやすい例に、 Django モデルオブジェクトの :meth:`~django.db.models.Models.delete` メソッドがあります。テンプレート システムでは、以下のような書き方を許すべきではありません:: 大事なデータを消しちゃいますよ。 {{ data.delete }} .. To prevent this, set an ``alters_data`` attribute on the callable variable. The template system won't call a variable if it has ``alters_data=True`` set, and will instead replace the variable with :setting:`TEMPLATE_STRING_IF_INVALID`, unconditionally. The dynamically-generated :meth:`~django.db.models.Model.delete` and :meth:`~django.db.models.Model.save` methods on Django model objects get ``alters_data=True`` automatically. Example:: このような操作を防ぐには、呼び出し可能変数に ``alters_data`` 属性を設定し ます。テンプレートシステムは、 ``alters_data=True`` が設定された変数の 呼び出しは行いません。 Django モデルオブジェクトが動的に生成する :meth:`django.db.models.Model.delete` および :meth:`django.db.models.Model.save` メソッドには ``alters_data=True`` が自 動的に設定されます。 ``alters_data=True`` の例を以下に示します:: def sensitive_function(self): self.database_record.delete() sensitive_function.alters_data = True .. * .. versionadded:: 1.4 Occasionally you may want to turn off this feature for other reasons, and tell the template system to leave a variable un-called no matter what. To do so, set a ``do_not_call_in_templates`` attribute on the callable with the value ``True``. The template system then will act as if your variable is not callable (allowing you to access attributes of the callable, for example). * .. versionadded:: 1.4 ときにはデータ変更を防ぐ以外の目的で、この機能を無効化してテンプレート システムから変数を一切呼び出さないで欲しいと思うこともあるでしょう。 そうするには、その呼び出し可能オブジェクトに ``do_not_call_in_templates`` 属性を設定し、その値を ``True`` にします。こうするとテンプレートシステムは あたかもその変数が呼び出し可能オブジェクトではない場合と同じように扱います (その呼び出し可能オブジェクトの属性へのアクセスなども可能になります)。 .. _invalid-template-variables: 無効な値の扱い ~~~~~~~~~~~~~~ 基本的に、変数が存在しなければ、 テンプレートシステムは :setting:`TEMPLATE_STRING_IF_INVALID` の設定値を挿入します。この値のデフォルトは ``''`` (空文字列) です。 無効な値に対してフィルタが適用されるのは、 :setting:`TEMPLATE_STRING_IF_INVALID` の値が ``''`` に設定されている場合だ けです。 :setting:`TEMPLATE_STRING_IF_INVALID` が ``''`` 以外の値になってい ると、フィルタは無視されます。 ただし、 ``if``, ``for``, ``regroup`` といったテンプレートタグの中では、少 し違った挙動になります。これらのテンプレートタグ中では、無効な値は ``None`` であると解釈されます。また、これらのテンプレートタグ中のフィルタは、無効な 値に対しも常に適用されます。 :setting:`TEMPLATE_STRING_IF_INVALID` にフォーマット指示文字の ``'%s'`` が 入っている場合、 ``'%s'`` は不正な変数の変数名で置き換えられます。 .. admonition:: デバッグ専用です! :setting:`TEMPLATE_STRING_IF_INVALID` はデバッグには便利ですが、「開発 時のデフォルトの設定」としてオンにするのはよい考えではありません。 Admin サイトのテンプレートをはじめとする多くのテンプレートは、実在し ない値を呼び出しても何も出力しないという動作を前提に作られています。 ``''`` 以外の値を :setting:`TEMPLATE_STRING_IF_INVALID` に指定した場合、 こうしたテンプレートやサイトのレンダリングで問題が生じるかもしれません。 一般に、 :setting:`TEMPLATE_STRING_IF_INVALID` を有効にするのは特定のテ ンプレートに対する問題を解決したいときだけにして、デバッグが終わったら すぐに無効にしておくべきです。 コンテキストオブジェクトの操作 ------------------------------ .. class:: django.template.Context 皆さんはほとんどの場合、全ての値を入れた辞書を ``Context()`` に渡して ``Context`` オブジェクトのインスタンスを生成していることでしょう。しかし、 ``Context`` オブジェクトはインスタンス化した後にも、通常の辞書と同じように 値を追加したり削除したりできます:: >>> c = Context({"foo": "bar"}) >>> c['foo'] 'bar' >>> del c['foo'] >>> c['foo'] '' >>> c['newvariable'] = 'hello' >>> c['newvariable'] 'hello' .. method:: pop() .. method:: push() .. exception:: django.template.ContextPopException ``Context`` オブジェクトは一種のスタックです。すなわち、 ``push()`` や ``pop()`` 操作を行えます。 ``pop()`` しすぎると、 ``django.template.ContextPopException`` を送出します:: >>> c = Context() >>> c['foo'] = 'first level' >>> c.push() >>> c['foo'] = 'second level' >>> c['foo'] 'second level' >>> c.pop() >>> c['foo'] 'first level' >>> c['foo'] = 'overwritten' >>> c['foo'] 'overwritten' >>> c.pop() Traceback (most recent call last): ... django.template.ContextPopException .. method:: update(other_dict) .. In addition to ``push()`` and ``pop()``, the ``Context`` object also defines an ``update()`` method. This works like ``push()`` but takes a dictionary as an argument and pushes that dictionary onto the stack instead of an empty one. ``push()`` と ``pop()`` に加え、 ``Context`` オブジェクトは ``update()`` メソッドも定義しています。これは ``push()`` と同じように動作しますが、 空の辞書ではなく引数で受け取った辞書をスタックに追加します。 >>> c = Context() >>> c['foo'] = 'first level' >>> c.update({'foo': 'updated'}) {'foo': 'updated'} >>> c['foo'] 'updated' >>> c.pop() {'foo': 'updated'} >>> c['foo'] 'first level' ``Context`` をスタック的に使うと、後述するカスタムテンプレートタグで便利な ことがあります。 .. _subclassing-context-requestcontext: コンテキストのサブクラス: RequestContext ---------------------------------------- .. class:: django.template.RequestContext Django には ``django.template.RequestContext`` という特別なコンテキストクラ スがあります。このクラスは通常の ``django.template.Context`` とは少し異なる 部分があります。まず、 ``RequestContext`` は第一引数に :class:`~django.http.HttpRequest` をとります。例えば:: c = RequestContext(request, { 'foo': 'bar', }) 第二に、 ``RequestContext`` は :setting:`TEMPLATE_CONTEXT_PROCESSORS` 設定 に従っていくつかの値を自動的にコンテキストに入れます。 :setting:`TEMPLATE_CONTEXT_PROCESSORS` 設定は呼び出し可能オブジェクトのタプルになっ ています。個々の呼び出し可能オブジェクトは **コンテキストプロセッサ** と呼 ばれ、リクエストオブジェクトを引数にとって。何らかの値を要素に持った辞書を 返します。この辞書はコンテキストオブジェクトに統合されます。デフォルトでは、 :setting:`TEMPLATE_CONTEXT_PROCESSORS` は以下のようになっています:: ("django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.contrib.messages.context_processors.messages") .. .. versionadded:: 1.2 In addition to these, ``RequestContext`` always uses ``django.core.context_processors.csrf``. This is a security related context processor required by the admin and other contrib apps, and, in case of accidental misconfiguration, it is deliberately hardcoded in and cannot be turned off by the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting. .. versionadded:: 1.2 これらに加えて ``RequestContext`` は常に ``django.core.context_processors.csrf`` を使用します。これはセキュリティ関係 のコンテキストプロセッサで、admin やその他の contrib アプリケーションが 必要としており、そして誤って設定ミスをした場合に備えて意図的にハードコードさ れていて、 :setting:`TEMPLATE_CONTEXT_PROCESSORS` の設定で無効化できません。 .. .. versionadded:: 1.2 The ``'messages'`` context processor was added. For more information, see the :doc:`messages documentation `. .. versionadded:: 1.2 ``'messages'`` コンテキストプロセッサが追加されました。詳細については :doc:`メッセージフレームワーク ` を参照してください。 .. .. versionchanged:: 1.2 The auth context processor was moved in this release from its old location ``django.core.context_processors.auth`` to ``django.contrib.auth.context_processors.auth``. .. versionchanged:: 1.2 auth コンテキストプロセッサは ``django.core.context_processors.auth`` から ``django.contrib.auth.context_processors.auth`` へと移動しました。 各プロセッサはタプルに列挙した順に適用されます。従って、あるプロセッサが ある変数をコンテキストに入れた後、別のプロセッサが同じ名前の変数を入れれば、 後者が前者の内容を上書きします。デフォルトのプロセッサについては後で説明し ます。 .. .. admonition:: When context processors are applied When you use ``RequestContext``, the variables you supply directly are added first, followed any variables supplied by context processors. This means that a context processor may overwrite a variable you've supplied, so take care to avoid variable names which overlap with those supplied by your context processors. .. admonition:: コンテキストプロセッサが適用されるタイミング ``RequestContext`` には、最初にあなた自身が提供する変数がまず追加され、 その後にコンテキストプロセッサの提供する変数が追加されます。したがって、 コンテキストプロセッサはあなたが提供した変数を上書きする可能性がありますの で、コンテキストプロセッサが提供する変数と同じ変数名を避けるよう気をつけて ください。 ``RequestContext`` にはオプションの第三引数 ``processors`` に追加のプロセッ サのリストを指定できます。下記の例では、 ``RequestContext`` に ``ip_address`` 変数が入ります:: def ip_address_processor(request): return {'ip_address': request.META['REMOTE_ADDR']} def some_view(request): # ... c = RequestContext(request, { 'foo': 'bar', }, [ip_address_processor]) return HttpResponse(t.render(c)) .. .. note:: If you're using Django's :func:`~django.shortcuts.render_to_response()` shortcut to populate a template with the contents of a dictionary, your template will be passed a ``Context`` instance by default (not a ``RequestContext``). To use a ``RequestContext`` in your template rendering, pass an optional third argument to :func:`~django.shortcuts.render_to_response()`: a ``RequestContext`` instance. Your code might look like this:: .. note:: Django の :func:`~django.shortcuts.render_to_response()` ショートカットを 使っていて、辞書オブジェクトを渡してコンテキストの変数を追加している場合、 テンプレートはデフォルトで (``RequestContext`` ではなく) ``Context`` になります。テンプレートのレンダリングに ``RequestContext`` を使うには、 :func:`~django.shortcuts.render_to_response()` の 3 つめの引数に ``RequestContext`` インスタンスを指定します。 コードは以下のようになるでしょう:: def some_view(request): # ... return render_to_response('my_template.html', my_data_dictionary, context_instance=RequestContext(request)) 各デフォルトプロセッサの動作を以下に示します: django.contrib.auth.context_processors.auth ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ このプロセッサが :setting:`TEMPLATE_CONTEXT_PROCESSORS` にある場合、以下の 3 つの変数が ``RequestContext`` に入ります: * ``user`` -- 現在ログインしているユーザを表す ``auth.User`` インスタン ス (クライアントがログインしていない場合には ``AnonymousUser`` インス タンス) です。 * ``perms`` -- 現在ログインしているユーザが有しているパーミッションを表 す、 ``django.contrib.auth.context_processors.PermWrapper`` のインス タンスです。 .. .. versionchanged:: 1.2 This context processor was moved in this release from ``django.core.context_processors.auth`` to its current location. .. versionchanged:: 1.2 このコンテキストプロセッサは ``django.core.context_processors.auth`` から現在の場所に移動されました。 .. .. versionchanged:: 1.3 Prior to version 1.3, ``PermWrapper`` was located in ``django.contrib.auth.context_processors``. .. versionchanged:: 1.3 バージョン 1.3 より前では、 ``PermWrapper`` は ``django.contrib.auth.context_processors`` にありました。 django.core.context_processors.debug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ このプロセッサが :setting:`TEMPLATE_CONTEXT_PROCESSORS` にある場合、以下の 2 つの変数が ``RequestContext`` に入ります。ただし、 ``DEBUG`` の設定が ``True`` で、リクエストの IP アドレス (``request.META['REMOTE_ADDR']``) が :setting:`INTERNAL_IPS` 設定に入っている場合だけです: * ``debug`` -- ``True`` です。 :setting:`DEBUG` モードかどうかをテスト するのに使えます。 * ``sql_queries`` -- ``{'sql': ..., 'time': ...}`` 辞書のリストです。 このリストはリクエスト処理中に実行された SQL クエリと、それにかかった 時間を表しています。リストはクエリの実行順にならんでいます。 django.core.context_processors.i18n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ このプロセッサが :setting:`TEMPLATE_CONTEXT_PROCESSORS` にある場合、以下の 2 つの変数が ``RequestContext`` に入ります: * ``LANGUAGES`` -- :setting:`LANGUAGES` 設定の値です。 * ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE`` が存在する場合、その値 です。値がなければ :setting:`LANGUAGE_CODE` 設定の値になります。 詳しくは :doc:`/topics/i18n/index` を参照してください。 django.core.context_processors.media ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :setting:`TEMPLATE_CONTEXT_PROCESSORS` にこのコンテキストプロセッサを入れる と、 ``RequestContext`` に ``MEDIA_URL`` というコンテキスト変数が入ります。 ``MEDIA_URL`` には :setting:`MEDIA_URL` 設定の値が入っています。 django.core.context_processors.static ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. function:: django.core.context_processors.static .. versionadded:: 1.3 .. If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every ``RequestContext`` will contain a variable ``STATIC_URL``, providing the value of the :setting:`STATIC_URL` setting. :setting:`TEMPLATE_CONTEXT_PROCESSORS` にこのコンテキストプロセッサを入れる と、 ``RequestContext`` に ``STATIC_URL`` というコンテキスト変数が入ります。 ``STATIC_URL`` には :setting:`STATIC_URL` 設定の値が入っています。 django.core.context_processors.csrf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.2 .. This processor adds a token that is needed by the :ttag:`csrf_token` template tag for protection against :doc:`Cross Site Request Forgeries `. このコンテキストプロセッサは :ttag:`csrf_token` テンプレートタグが :doc:`クロスサイトリクエストフォージェリ` 対策のために 必要とするトークンを追加します。 django.core.context_processors.request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ このプロセッサが :setting:`TEMPLATE_CONTEXT_PROCESSORS` にある場合、変数 ``request`` が ``RequestContext`` に入ります。この変数は現在の :class:`~django.http.HttpRequest` を表現します。このプロセッサはデフォルト では有効でないので注意してください。利用したければ有効にせねばなりません。 django.contrib.messages.context_processors.messages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every ``RequestContext`` will contain a single additional variable: このプロセッサが :setting:`TEMPLATE_CONTEXT_PROCESSORS` にある場合、変数が 一つ ``RequestContext`` に追加されます: .. * ``messages`` -- A list of messages (as strings) that have been set via the user model (using ``user.message_set.create``) or through the :doc:`messages framework `. * ``messages`` -- ユーザモデルを通して (``user.message_set.create`` を使って) 設定されたか、 :doc:`メッセージフレームワーク ` を 通して設定されたメッセージ (文字列) のリスト。 .. .. versionadded:: 1.2 This template context variable was previously supplied by the ``'auth'`` context processor. For backwards compatibility the ``'auth'`` context processor will continue to supply the ``messages`` variable until Django 1.4. If you use the ``messages`` variable, your project will work with either (or both) context processors, but it is recommended to add ``django.contrib.messages.context_processors.messages`` so your project will be prepared for the future upgrade. .. versionadded:: 1.2 このテンプレートコンテキスト変数はこれまで ``'auth'`` コンテキストプロセッサ が提供してきました。後方互換性のため ``'auth'`` コンテキストプロセッサは Django 1.4 までは ``messages`` 変数を提供し続けます。もし ``messages`` 変数を使う場合、あなたのプロジェクトはどちらの (または両方の) コンテキスト プロセッサを使っても動作するでしょうけれども、将来のアップグレードに備えて ``django.contrib.messages.context_processors.messages`` を追加することを 推奨します。 コンテキストプロセッサを自作する ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ コンテキストプロセッサのインタフェースはとても簡単です。コンテキストプロセッ サは単なる Python の関数で、 :class:`~django.http.HttpRequest` オブジェクトを 引数にとり、テンプレートコンテキストに追加できるような辞書を返します。 コンテキストプロセッサは、 **必ず** 辞書型を返さねばなりません。 自分のコードベースに自作のコンテキストプロセッサを入れてもかまいません。 Django 側からは、自作のコンテキストプロセッサを :setting:`TEMPLATE_CONTEXT_PROCESSORS` 設定で指定するようにしてください。 テンプレートのロード -------------------- 一般的には、低水準の ``Template`` API を自分で使うことはほとんどなく、テン プレートはファイルの形でファイルシステム上に保存することになるでしょう。 **テンプレートディレクトリ** に指定したディレクトリにテンプレートファイルを 保存してください。 Django はテンプレートローダの設定 (「Loader 型」を参照してください) に従って、いくつものテンプレートディレクトリを検索しますが、最も基本的なテ ンプレートディレクトリ指定方法は :setting:`TEMPLATE_DIRS` を使う方法です。 TEMPLATE_DIRS 設定 ~~~~~~~~~~~~~~~~~~ 設定ファイル中で、 :setting:`TEMPLATE_DIRS` 設定を使ってどのディレクトリに テンプレートが収められているかを指定してください。この値は文字列のリストか タプルで指定します。文字列にはテンプレートディレクトリへの完全なパスを指定 せねばなりません。例えば:: TEMPLATE_DIRS = ( "/home/html/templates/lawrence.com", "/home/html/templates/default", ) Web サーバがテンプレートディレクトリの中身を読みだせる限り、テンプレートは どこにでも置けます。拡張子はなんでもよく、 ``.html`` でも ``.txt`` でも かまいませんし、拡張子を付けなくてもかまいません。 Windows を使っている場合でも、パスは Unix 形式のスラッシュを使った表記法で 指定せねばならないので注意して下さい。 .. _ref-templates-api-the-python-api: Python API ~~~~~~~~~~~~~~ Django でファイルからテンプレートを読み出すには二通りの方法があります: .. function:: django.template.loader.get_template(template_name) ``get_template`` は、指定した名前のテンプレートに対応したコンパイル済み のテンプレート (``Template`` オブジェクト) を返します。テンプレートが存 在しなければ ``django.template.TemplateDoesNotExist`` を送出します。 .. function:: django.template.loader.select_template(template_name_list) ``select_template`` は ``get_template`` と同じです。ただし、テンプレー ト名のリストを引数にとります。リストの中で最初に見つかったテンプレート を返します。 例えば ``get_template('story_detail.html')`` を呼び出した場合、前述のような :setting:`TEMPLATE_DIRS` の設定をしていれば、Django は以下のような順番でテ ンプレートファイルを探します: * ``/home/html/templates/lawrence.com/story_detail.html`` * ``/home/html/templates/default/story_detail.html`` ``select_template(['story_253_detail.html', 'story_detail.html'])`` なら、 以下の順で探します: * ``/home/html/templates/lawrence.com/story_253_detail.html`` * ``/home/html/templates/default/story_253_detail.html`` * ``/home/html/templates/lawrence.com/story_detail.html`` * ``/home/html/templates/default/story_detail.html`` テンプレートが見つかった時点で Django は検索を停止します。 .. admonition:: Tip ``select_template()`` を使うと、極めて柔軟な「テンプレート構成機能 (templatability)」を実現できます。例えば、あるニュース記事を書いていて、 記事によってはカスタムのテンプレートを使いたいとします。 ``select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])`` のようにすると、個々の記事にカスタムのテンプレートを使いながら、カスタ ムのテンプレートがない記事に対してはフォールバックのテンプレートを用意 できるというわけです。 サブディレクトリの使用 ~~~~~~~~~~~~~~~~~~~~~~~ テンプレートディレクトリを複数のサブディレクトリで構成するのは可能ですし、 お勧めでもあります。慣習的には各 Django アプリケーション毎にサブディレク トリを作成します。必要に応じてさらにサブディレクトリを作成します。 精神衛生のためにもぜひテンプレートを階層化しましょう。一つのディレクトリの ルートレベルに全てのテンプレートを保存するのは、だらしないことこの上ありま せん。 サブディレクトリ下にあるテンプレートをロードするには、以下のようにスラッシュ を使って指定します:: get_template('news/story_detail.html') この例の ``get_template()`` は、上の :setting:`TEMPLATE_DIRS` と同じ設定を 使った場合、以下の順番でテンプレートをロードしようと試みます: * ``/home/html/templates/lawrence.com/news/story_detail.html`` * ``/home/html/templates/default/news/story_detail.html`` .. _template-loaders: Loader 型 ~~~~~~~~~ デフォルトでは、 Django はファイルシステムベースのテンプレートローダを使っ ていますが、 Django には他のテンプレートローダも付属しており、その他のデー タソースからテンプレートをロードできるようになっています。 ファイルシステムベース以外のテンプレートローダはデフォルトでは無効化されて いますが、 :setting:`TEMPLATE_LOADERS` 設定を編集して有効にできます。 :setting:`TEMPLATE_LOADERS` は文字列のタプルで、各文字列がテンプレートロー ダクラスを表します。組み込みのテンプレートローダを以下に示します: .. .. versionchanged:: 1.2 Template loaders were based on callables (usually functions) before Django 1.2, starting with the 1.2 release there is a new class-based API, all the loaders described below implement this new API. .. versionchanged:: 1.2 1.2 より前の Django ではテンプレートローダは呼び出し可能オブジェクト (普通 は関数) をベースにしていましたが、 1.2 リリースからは新しいクラスベースの API が提供され、以下で説明するすべてのローダーはこの新しい API を実装して います。 ``django.template.loaders.filesystem.Loader`` :setting:`TEMPLATE_DIRS` の設定に従って、ファイルシステムからテンプレー トをロードします。 ``django.template.loaders.app_directories.Loader`` ファイルシステム上の Django アプリケーションからテンプレートをロードし ます。このローダは :setting:`INSTALLED_APPS` の各アプリケーションについ て ``templates`` サブディレクトリを探します。ディレクトリが存在すれば、 Django はその中からテンプレートを探します。 これはすなわち、個々のアプリケーションにテンプレートを保存しておけると いうことです。このローダを使うと、 Django アプリケーションをデフォルト のテンプレート付きで配りやすくなります。 例えば、以下のように設定します:: INSTALLED_APPS = ('myproject.polls', 'myproject.music') ``get_template('foo.html')`` は以下のディレクトリを順番に探します: * ``/path/to/myproject/polls/templates/foo.html`` * ``/path/to/myproject/music/templates/foo.html`` このローダは最初に import した時に最適化処理を行います。すなわち、 :setting:`INSTALLED_APPS` パッケージリストの中で、 ``templates`` サブディ レクトリを持つものをキャッシュします。 このローダはデフォルトで有効化されています。 ``django.template.loaders.eggs.Loader`` ``app_directories`` と同じですが、ファイルシステムではなく Python eggs からテンプレートをロードします。 このローダはデフォルトで無効化されています。 ``django.template.loaders.cached.Loader`` .. By default, the templating system will read and compile your templates every time they need to be rendered. While the Django templating system is quite fast, the overhead from reading and compiling templates can add up. デフォルトでは、テンプレートシステムはレンダリングが必要になるたびにテンプ レートを読み出してコンパイルします。 Django のテンプレートシステムは非常に 高速ですが、読み出しとコンパイルのオーバーヘッドが積み重なっていく可能性は あります。 .. The cached template loader is a class-based loader that you configure with a list of other loaders that it should wrap. The wrapped loaders are used to locate unknown templates when they are first encountered. The cached loader then stores the compiled ``Template`` in memory. The cached ``Template`` instance is returned for subsequent requests to load the same template. キャッシュドテンプレートローダ (cached template loader) はクラスベースの ローダで、ラッピングする他のローダのリストを指定して設定します。ラッピング されたローダは、未知のテンプレートが初めて現れたときに、その場所を特定する ために使われます。そしてキャッシュドテンプレートローダはコンパイルされた ``Template`` をメモリ上に格納します。キャッシュされた ``Template`` のインスタンスは、以後の同一テンプレートに対するリクエストで返されます。 .. For example, to enable template caching with the ``filesystem`` and ``app_directories`` template loaders you might use the following settings:: たとえば、 ``filesystem`` と ``app_directories`` テンプレートローダの テンプレートをキャッシュするには次のように設定します:: TEMPLATE_LOADERS = ( ('django.template.loaders.cached.Loader', ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', )), ) .. note:: .. All of the built-in Django template tags are safe to use with the cached loader, but if you're using custom template tags that come from third party packages, or that you wrote yourself, you should ensure that the ``Node`` implementation for each tag is thread-safe. For more information, see :ref:`template tag thread safety considerations`. すべての組み込み Django テンプレートタグはキャッシュされたローダで 安全に扱えますが、もしサードパーティ製あるいはあなた自身が書いた カスタムテンプレートタグを使っている場合、各タグの ``Node`` の実装が スレッドセーフになっていることを確認しておくべきでしょう。詳細について は、 :ref:`テンプレートタグのスレッドセーフ性を考慮する ` を参照してください。 .. This loader is disabled by default. このローダはデフォルトで無効化されています。 Django はテンプレートローダを :setting:`TEMPLATE_LOADERS` 設定の順番に従っ て試してゆき、マッチするテンプレートが見つかるまで探します。 ``render_to_string`` ショートカット =================================== .. function:: django.template.loader.render_to_string(template_name, dictionary=None, context_instance=None) テンプレートのロードとレンダの反復を減らすため、 Django は作業を自動化する ためのショートカットとして、 :mod:`django.template.loader` で ``render_to_string()`` を提供しています。このショートカットは、テンプレート をロードし、レンダして、結果を文字列として返します:: from django.template.loader import render_to_string rendered = render_to_string('my_template.html', { 'foo': 'bar' }) .. The ``render_to_string`` shortcut takes one required argument -- ``template_name``, which should be the name of the template to load and render (or a list of template names, in which case Django will use the first template in the list that exists) -- and two optional arguments: ``render_to_string`` ショートカットは、必須の引数として、レンダリング時にロー ドするテンプレートの名前 ``template_name`` (またはテンプレート名のリスト。 この場合 Django はリスト中で最初に現れた、存在するテンプレートを使用します) をとります。また、オプション引数を二つとります: dictionary テンプレートのコンテキストとして使う値の入った辞書です。第二固定引 数として渡しても構いません。 context_instance ``Context`` またはサブクラス (例えば ``RequestContext``) のインスタ ンスです。テンプレートのコンテキストとして使われます。第三固定引数 として渡してもかまいません。 :func:`~django.shortcuts.render_to_response()` ショートカットも参照してくだ さい。このショートカットは、結果を :class:`~django.http.HttpResponse` に入れて、ビューからレンダ内容を直接返せるようにしています。 .. _ref-templates-configuring-standalone: テンプレートシステムをスタンドアロンモードに設定する ==================================================== .. note:: この節は、テンプレートシステムを他のアプリケーションの出力用コンポーネ ントとして使ってみたいと考えている人のためのものです。テンプレートシス テムを Django の一部として使っている人には、この節の内容はあてはまりま せん。 通常、 Django は必要な全ての設定情報を、デフォルトの設定ファイル上の設定と 環境変数 :envvar:`DJANGO_SETTING_FILE` に指定したファイル上の設定を合わせ たものからロードします。ただし、 Django の他の部分からテンプレートシステム を切り離して使いたい場合は、環境変数を介して設定ファイルを扱うよりも、アプ リケーション内でテンプレートシステムを初期化したいでしょうから、環境変数を 使う方法はあまり便利とはいえないでしょう。 この問題を解決するためには、 :ref:`settings-without-django-settings-module` に書かれている手動設定の方法を使う必要があります。テンプレートシステムの必 要な部分を import して、何らかのテンプレート関連の関数を呼ぶ *前に* 、指定 したい設定を引数にして :func:`django.conf.settings.configure()` を呼び出して下さ い。少なくとも :setting:`TEMPLATE_DIRS` (テンプレートローダを使いたい場合), :setting:`DEFAULT_CHARSET` (通常はデフォルトの ``utf-8`` で十分です), :setting:`TEMPLATE_DEBUG` などを設定することになるでしょう。設定可能な変数 は、 :doc:`設定ファイルのドキュメント ` に書かれています。関 係のある変数は ``TEMPLATE_`` で始まっている設定です。 .. _topic-template-alternate-language: .. Using an alternative template language ====================================== 異なるテンプレート言語を使う ============================ .. versionadded:: 1.2 .. The Django ``Template`` and ``Loader`` classes implement a simple API for loading and rendering templates. By providing some simple wrapper classes that implement this API we can use third party template systems like `Jinja2 `_ or `Cheetah `_. This allows us to use third-party template libraries without giving up useful Django features like the Django ``Context`` object and handy shortcuts like :func:`~django.shortcuts.render_to_response()`. Django の ``Template`` クラスと ``Loader`` クラスはテンプレートをロード・レンダ リングするためのシンプルな API を実装しています。この API を実装するシンプルな ラッパークラスを提供すれば、 `Jinja2 `_ や `Cheetah `_ といったサードパーティのテンプレートシステ ムを使用することも可能です。こうすることで、 ``Context`` オブジェクトや :func:`~django.shortcuts.render_to_response()` などの使いやすいショートカットと いった Django の役立つ機能をあきらめることなくサードパーティのテンプレートライ ブラリを使うことができます。 .. The core component of the Django templating system is the ``Template`` class. This class has a very simple interface: it has a constructor that takes a single positional argument specifying the template string, and a ``render()`` method that takes a :class:`~django.template.Context` object and returns a string containing the rendered response. Django のテンプレートシステムのコアコンポーネントは ``Template`` クラスです。 このクラスは非常にシンプルなインタフェースを備えています: テンプレート文字列を 指定する引数を一つ取るコンストラクタと、 :class:`~django.template.Context` オブジェクトを受け取りレンダリングされたレスポンスを文字列を返す ``render()`` メソッドです。 .. Suppose we're using a template language that defines a ``Template`` object with a ``render()`` method that takes a dictionary rather than a ``Context`` object. We can write a simple wrapper that implements the Django ``Template`` interface:: たとえば、``Context`` オブジェクトではなく辞書オブジェクトを受け取るような ``render()`` メソッドを備えた ``Template`` オブジェクトを定義しているテンプレー ト言語を私たちが使っているとしましょう。その場合、 Django の ``Template`` のイ ンタフェースを実装する次のような簡単なラッパーを書くことができます:: import some_template_language class Template(some_template_language.Template): def render(self, context): # flatten the Django Context into a single dictionary. context_dict = {} for d in context.dicts: context_dict.update(d) return super(Template, self).render(context_dict) .. That's all that's required to make our fictional ``Template`` class compatible with the Django loading and rendering system! これだけで、私たちの空想の ``Template`` クラスを Django のロード・レンダリングの システムで使えるようになります! .. The next step is to write a ``Loader`` class that returns instances of our custom template class instead of the default :class:`~django.template.Template`. Custom ``Loader`` classes should inherit from ``django.template.loader.BaseLoader`` and override the ``load_template_source()`` method, which takes a ``template_name`` argument, loads the template from disk (or elsewhere), and returns a tuple: ``(template_string, template_origin)``. 次のステップは、標準の :class:`~django.template.Template` のかわりに私たちの カスタムテンプレートクラスのインスタンスを返す ``Loader`` クラスを書くことです。 カスタム ``Loader`` クラスは ``django.template.loader.BaseLoader`` を継承し、 ``load_template_source()`` メソッドをオーバーライドするべきです。このメソッドは ``template_name`` 引数を受け取ってテンプレートをディスク (または他のどこか) からロードし、次のタプルを返します: ``(template_string, template_origin)``。 .. The ``load_template()`` method of the ``Loader`` class retrieves the template string by calling ``load_template_source()``, instantiates a ``Template`` from the template source, and returns a tuple: ``(template, template_origin)``. Since this is the method that actually instantiates the ``Template``, we'll need to override it to use our custom template class instead. We can inherit from the builtin :class:`django.template.loaders.app_directories.Loader` to take advantage of the ``load_template_source()`` method implemented there:: ``Loader`` クラスの ``load_template()`` メソッドは、テンプレート文字列を ``load_template_source()`` を呼び出して取得し、テンプレートソースから ``Template`` をインスタンス化して、次のタプルを返します: ``(template, template_origin)``。実際には ``Template`` はこのようにインスタンス 化されるので、カスタムテンプレートクラスを代わりに使うためには ``load_template_source()`` メソッドのオーバーライドが必要、というわけです。 また :class:`django.template.loaders.app_directories.Loader` を継承すると、 その ``load_template_source()`` メソッドの実装を利用することもできます:: from django.template.loaders import app_directories class Loader(app_directories.Loader): is_usable = True def load_template(self, template_name, template_dirs=None): source, origin = self.load_template_source(template_name, template_dirs) template = Template(source) return template, origin .. Finally, we need to modify our project settings, telling Django to use our custom loader. Now we can write all of our templates in our alternative template language while continuing to use the rest of the Django templating system. 最後に、 Django にカスタムローダを使わせるようプロジェクト設定を変更する 必要があります。以上で、 Django の他の機能を使いつつ、異なるテンプレート言語で すべてのテンプレートを書けるようになりました。