Djangoテンプレート言語:Pythonプログラマー向け—Djangoドキュメント
Djangoテンプレート言語:Pythonプログラマー向け
このドキュメントでは、Djangoテンプレートシステムを技術的な観点から説明します–それがどのように機能し、どのように拡張するか。 言語構文のリファレンスを探している場合は、 Djangoテンプレート言語を参照してください。
テンプレート、コンテキスト、変数、タグ、およびレンダリングについて理解していることを前提としています。 これらの概念に慣れていない場合は、 Djangoテンプレート言語の概要から始めてください。
概要
Pythonでテンプレートシステムを使用することは、3つのステップのプロセスです。
Djangoプロジェクトは通常、テンプレートシステムの低レベルAPIではなく、これらの各ステップで高レベルのバックエンドに依存しないAPI に依存しています。
- :setting: `TEMPLATES` 設定の DjangoTemplates バックエンドごとに、Djangoは Engine をインスタンス化します。 DjangoTemplates は、 Engine をラップし、それを共通のテンプレートバックエンドAPIに適合させます。
- django.template.loader モジュールは、テンプレートをロードするための get_template()などの関数を提供します。 それらは、実際の django.template.Template をラップする
django.template.backends.django.Template
を返します。 - 前のステップで取得した
Template
には、 render()メソッドがあり、コンテキストと場合によってはリクエストを Context にマーシャリングし、レンダリングを基になるに委任します。 ]テンプレート。
エンジンの構成
DjangoTemplates バックエンドを使用している場合、これはおそらく探しているドキュメントではありません。 以下で説明するEngine
クラスのインスタンスは、そのバックエンドのengine
属性を使用してアクセスでき、以下で説明する属性のデフォルトは、 DjangoTemplates によって渡されるものによって上書きされます。
- class Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid=, file_charset='utf-8', libraries=None, builtins=None, autoescape=True)
Engine
をインスタンス化するときは、すべての引数をキーワード引数として渡す必要があります。dirs
は、エンジンがテンプレートソースファイルを探す必要があるディレクトリのリストです。 filesystem.Loader を構成するために使用されます。デフォルトでは空のリストになります。
app_dirs
は、デフォルト値のloaders
にのみ影響します。 下記参照。デフォルトは
False
です。autoescape
は、HTML自動エスケープを有効にするかどうかを制御します。デフォルトは
True
です。警告
HTML以外のテンプレートをレンダリングする場合にのみ、
False
に設定してください。context_processors
は、テンプレートがリクエストでレンダリングされるときにコンテキストにデータを入力するために使用される呼び出し可能オブジェクトへの点線のPythonパスのリストです。 これらの呼び出し可能オブジェクトは、引数として要求オブジェクトを受け取り、コンテキストにマージされるアイテムのdict
を返します。デフォルトでは空のリストになります。
詳細については、 RequestContext を参照してください。
debug
は、テンプレートのデバッグモードをオン/オフにするブール値です。True
の場合、テンプレートエンジンは、テンプレートのレンダリング中に発生した例外の詳細レポートを表示するために使用できる追加のデバッグ情報を格納します。デフォルトは
False
です。loaders
は、文字列として指定されたテンプレートローダークラスのリストです。 各Loader
クラスは、特定のソースからテンプレートをインポートする方法を知っています。 オプションで、文字列の代わりにタプルを使用できます。 タプルの最初の項目はLoader
クラス名である必要があり、後続の項目は初期化中にLoader
に渡されます。デフォルトでは、以下を含むリストになります。
'django.template.loaders.filesystem.Loader'
'django.template.loaders.app_directories.Loader'
は、app_dirs
がTrue
である場合に限ります。
debug
がFalse
の場合、これらのローダーは django.template.loaders.cached.Loader でラップされます。詳細については、ローダータイプを参照してください。
string_if_invalid
は、テンプレートシステムが無効に使用する必要がある文字列としての出力です(例: スペルミス)変数。デフォルトは空の文字列です。
詳細については、無効な変数の処理方法を参照してください。
file_charset
は、ディスク上のテンプレートファイルを読み取るために使用される文字セットです。デフォルトは
'utf-8'
です。'libraries'
:テンプレートエンジンに登録するためのテンプレートタグモジュールのラベルと点線のPythonパスの辞書。 これは、新しいライブラリを追加したり、既存のライブラリの代替ラベルを提供したりするために使用されます。 例えば:Engine( libraries={ 'myapp_tags': 'path.to.myapp.tags', 'admin.urls': 'django.contrib.admin.templatetags.admin_urls', }, )
ライブラリは、対応する辞書キーをに渡すことでロードできます。 :ttag: `{%load%} ` 鬼ごっこ。
'builtins'
:ビルトインに追加するテンプレートタグモジュールの点線のPythonパスのリスト。 例えば:Engine( builtins=['myapp.builtins'], )
組み込みライブラリのタグとフィルタは、最初にを呼び出さなくても使用できます。 :ttag: `{%load%} ` 鬼ごっこ。
- static Engine.get_default()
最初に構成された DjangoTemplates エンジンから基盤となる Engine を返します。 エンジンが構成されていない場合、 ImpproperlyConfigured を発生させます。
これは、グローバルに利用可能な暗黙的に構成されたエンジンに依存するAPIを保持するために必要です。 その他の使用は強くお勧めしません。
- Engine.from_string(template_code)
- 指定されたテンプレートコードをコンパイルし、 Template オブジェクトを返します。
- Engine.get_template(template_name)
- 指定された名前のテンプレートをロードし、コンパイルして、 Template オブジェクトを返します。
- Engine.select_template(template_name_list)
- get_template()と同様ですが、名前のリストを取得し、最初に見つかったテンプレートを返す点が異なります。
テンプレートの読み込み
テンプレートを作成するための推奨される方法は、エンジンのファクトリメソッド get_template()、 select_template()、およびを呼び出すことです。 X164X] from_string()。
:setting: `TEMPLATES` 設定が DjangoTemplates エンジンを定義するDjangoプロジェクトでは、 Template を直接インスタンス化することができます。 複数の DjangoTemplates エンジンが定義されている場合は、最初のエンジンが使用されます。
- class Template
このクラスは
django.template.Template
に住んでいます。 コンストラクターは1つの引数を取ります—生のテンプレートコード:from django.template import Template template = Template("My name is {{ my_name }}.")
舞台裏
Template
オブジェクトを作成するときに、システムは生のテンプレートコードを1回だけ解析します。 それ以降は、パフォーマンスのためにツリー構造として内部に保存されます。
解析自体も非常に高速です。 解析のほとんどは、単一の短い正規表現への単一の呼び出しを介して行われます。
コンテキストのレンダリング
コンパイルされた Template オブジェクトを取得したら、それを使用してコンテキストをレンダリングできます。 同じテンプレートを再利用して、異なるコンテキストで複数回レンダリングできます。
- class Context(dict_=None)
django.template.Context
のコンストラクターは、オプションの引数(変数名を変数値にマッピングする辞書)を取ります。詳細については、以下のコンテキストオブジェクトでの再生を参照してください。
- Template.render(context)
Template オブジェクトの
render()
メソッドを Context で呼び出して、テンプレートを「塗りつぶし」ます。>>> from django.template import Context, Template >>> template = Template("My name is {{ my_name }}.") >>> context = Context({"my_name": "Adrian"}) >>> template.render(context) "My name is Adrian." >>> context = Context({"my_name": "Dolores"}) >>> template.render(context) "My name is Dolores."
変数とルックアップ
変数名は、任意の文字(AZ)、任意の数字(0〜9)、アンダースコア(ただし、アンダースコアで始まらない)、またはドットで構成する必要があります。
ドットは、テンプレートのレンダリングで特別な意味を持ちます。 変数名のドットは、ルックアップを示します。 具体的には、テンプレートシステムが変数名にドットを検出すると、次のルックアップをこの順序で試行します。
- 辞書検索。 例:
foo["bar"]
- 属性ルックアップ。 例:
foo.bar
- リストインデックスルックアップ。 例:
foo[bar]
テンプレート:Foo.bar
のようなテンプレート式の「bar」は、テンプレートコンテキストに存在する場合、変数「bar」の値を使用せずにリテラル文字列として解釈されることに注意してください。
テンプレートシステムは、機能する最初のルックアップタイプを使用します。 それは短絡論理です。 次にいくつかの例を示します。
>>> 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."
変数のいずれかの部分が呼び出し可能である場合、テンプレートシステムはそれを呼び出そうとします。 例:
>>> class PersonClass2:
... def name(self):
... return "Samantha"
>>> t = Template("My name is {{ person.name }}.")
>>> t.render(Context({"person": PersonClass2}))
"My name is Samantha."
呼び出し可能な変数は、ストレートルックアップのみを必要とする変数よりも少し複雑です。 覚えておくべきことがいくつかあります:
変数が呼び出されたときに例外が発生した場合、例外に属性
silent_variable_failure
があり、その値がTrue
でない限り、例外は伝播されます。 例外にsilent_variable_failure
属性があり、その値がTrue
の場合、変数はエンジンのstring_if_invalid
構成オプションの値としてレンダリングされます(空文字列、デフォルト)。 例:>>> 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
例外の基本クラスである django.core.exceptions.ObjectDoesNotExist には、silent_variable_failure = True
があることに注意してください。 したがって、DjangoモデルオブジェクトでDjangoテンプレートを使用している場合、DoesNotExist
例外はサイレントに失敗します。変数は、必要な引数がない場合にのみ呼び出すことができます。 それ以外の場合、システムはエンジンの
string_if_invalid
オプションの値を返します。
一部の変数を呼び出すと副作用が発生する可能性があり、テンプレートシステムがそれらにアクセスできるようにするのは愚かであるかセキュリティホールのいずれかです。
良い例は、各Djangoモデルオブジェクトの delete()メソッドです。 テンプレートシステムは、次のようなことを許可されるべきではありません。
I will now delete this valuable data. {{ data.delete }}
これを防ぐには、呼び出し可能変数に
alters_data
属性を設定します。 テンプレートシステムは、alters_data=True
が設定されている場合は変数を呼び出さず、代わりに無条件で変数をstring_if_invalid
に置き換えます。 Djangoモデルオブジェクトで動的に生成された delete()および save()メソッドは、alters_data=True
を自動的に取得します。 例:def sensitive_function(self): self.database_record.delete() sensitive_function.alters_data = True
場合によっては、他の理由でこの機能をオフにし、テンプレートシステムに、何があっても変数を呼び出さないままにするように指示することができます。 これを行うには、呼び出し可能オブジェクトに
do_not_call_in_templates
属性を値True
で設定します。 テンプレートシステムは、変数が呼び出し可能ではないかのように動作します(たとえば、呼び出し可能の属性にアクセスできるようにします)。
無効な変数の処理方法
通常、変数が存在しない場合、テンプレートシステムは、エンジンのstring_if_invalid
構成オプションの値を挿入します。これは、デフォルトで(空の文字列)に設定されています。
無効な変数に適用されるフィルターは、string_if_invalid
が(空の文字列)に設定されている場合にのみ適用されます。
string_if_invalid
が他の値に設定されている場合、変数フィルターは無視されます。
この動作は、if
、for
、およびregroup
テンプレートタグではわずかに異なります。 これらのテンプレートタグの1つに無効な変数が指定された場合、その変数はNone
として解釈されます。 フィルタは、これらのテンプレートタグ内の無効な変数に常に適用されます。
string_if_invalid
に'%s'
が含まれている場合、フォーマットマーカーは無効な変数の名前に置き換えられます。
デバッグのみを目的としています。
string_if_invalid
は便利なデバッグツールですが、「開発のデフォルト」としてオンにすることはお勧めできません。
一部のDjangoを含む多くのテンプレートは、存在しない変数が検出された場合のテンプレートシステムの無音に依存しています。 以外の値を
string_if_invalid
に割り当てると、これらのテンプレートとサイトでレンダリングの問題が発生します。
通常、string_if_invalid
は、特定のテンプレートの問題をデバッグするためにのみ有効にし、デバッグが完了したらクリアする必要があります。
組み込み変数
すべてのコンテキストには、True
、False
、およびNone
が含まれています。 ご想像のとおり、これらの変数は対応するPythonオブジェクトに解決されます。
文字列リテラルの制限
Djangoのテンプレート言語には、独自の構文に使用されている文字をエスケープする方法がありません。 たとえば、{%
や%}
などの文字シーケンスを出力する必要がある場合は、:ttag: `templatetag` タグが必要です。
これらのシーケンスをテンプレートフィルターまたはタグ引数に含めたい場合にも、同様の問題が存在します。 たとえば、ブロックタグを解析する場合、Djangoのテンプレートパーサーは{%
の後に最初に出現する%}
を探します。 これにより、"%}"
を文字列リテラルとして使用できなくなります。 たとえば、TemplateSyntaxError
は、次の式に対して発生します。
{% include "template.html" tvar="Some string literal with %} in it." %}
{% with tvar="Some string literal with %} in it." %}{% endwith %}
同じ問題は、フィルター引数で予約済みシーケンスを使用することでトリガーできます。
{{ some.variable|default:"}}" }}
これらのシーケンスで文字列を使用する必要がある場合は、それらをテンプレート変数に格納するか、カスタムテンプレートタグまたはフィルターを使用して制限を回避します。
Contextオブジェクトで遊ぶ
ほとんどの場合、完全に入力された辞書をContext()
に渡すことにより、 Context オブジェクトをインスタンス化します。 ただし、Context
オブジェクトがインスタンス化されたら、標準の辞書構文を使用して、アイテムを追加および削除することもできます。
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']
>>> c['foo']
Traceback (most recent call last):
...
KeyError: 'foo'
>>> c['newvariable'] = 'hello'
>>> c['newvariable']
'hello'
- Context.get(key, otherwise=None)
key
がコンテキスト内にある場合は、key
の値を返します。それ以外の場合は、otherwise
を返します。
- Context.setdefault(key, default=None)
key
がコンテキスト内にある場合、その値を返します。 それ以外の場合は、値がdefault
のkey
を挿入し、default
を返します。
- Context.pop()
- Context.push()
- exception 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()
{'foo': 'second level'}
>>> c['foo']
'first level'
>>> c['foo'] = 'overwritten'
>>> c['foo']
'overwritten'
>>> c.pop()
Traceback (most recent call last):
...
ContextPopException
push()
をコンテキストマネージャーとして使用して、一致するpop()
が呼び出されるようにすることもできます。
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.push():
... c['foo'] = 'second level'
... c['foo']
'second level'
>>> c['foo']
'first level'
push()
に渡されるすべての引数は、新しいコンテキストレベルの構築に使用されるdict
コンストラクターに渡されます。
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.push(foo='second level'):
... c['foo']
'second level'
>>> c['foo']
'first level'
- Context.update(other_dict)
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'
push()
と同様に、update()
をコンテキストマネージャーとして使用して、一致するpop()
が呼び出されるようにすることができます。
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.update({'foo': 'second level'}):
... c['foo']
'second level'
>>> c['foo']
'first level'
Context
をスタックとして使用すると、一部のカスタムテンプレートタグで役立ちます。
- Context.flatten()
flatten()
メソッドを使用すると、Context
スタック全体を組み込み変数を含む1つの辞書として取得できます。
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.update({'bar': 'second level'})
{'bar': 'second level'}
>>> c.flatten()
{'True': True, 'None': None, 'foo': 'first level', 'False': False, 'bar': 'second level'}
flatten()
メソッドは、Context
オブジェクトを比較可能にするために内部的にも使用されます。
>>> c1 = Context()
>>> c1['foo'] = 'first level'
>>> c1['bar'] = 'second level'
>>> c2 = Context()
>>> c2.update({'bar': 'second level', 'foo': 'first level'})
{'foo': 'first level', 'bar': 'second level'}
>>> c1 == c2
True
flatten()
の結果は、Context
をdict
と比較する単体テストで役立ちます。
class ContextTest(unittest.TestCase):
def test_against_dictionary(self):
c1 = Context()
c1['update'] = 'value'
self.assertEqual(c1.flatten(), {
'True': True,
'None': None,
'False': False,
'update': 'value',
})
RequestContextを使用する
- class RequestContext(request, dict_=None, processors=None)
Djangoには、通常のdjango.template.Context
とは少し異なる動作をする特別なContext
クラスdjango.template.RequestContext
が付属しています。 最初の違いは、最初の引数として HttpRequest を使用することです。 例えば:
c = RequestContext(request, {
'foo': 'bar',
})
2つ目の違いは、エンジンのcontext_processors
構成オプションに従って、コンテキストにいくつかの変数が自動的に入力されることです。
context_processors
オプションは、コンテキストプロセッサと呼ばれる呼び出し可能オブジェクトのリストであり、引数として要求オブジェクトを受け取り、コンテキストにマージされるアイテムのディクショナリを返します。 デフォルトで生成された設定ファイルでは、デフォルトのテンプレートエンジンに次のコンテキストプロセッサが含まれています。
[
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
]
これらに加えて、 RequestContext は常に'django.template.context_processors.csrf'
を有効にします。 これは、管理者やその他のcontribアプリに必要なセキュリティ関連のコンテキストプロセッサであり、誤って設定を誤った場合に備えて、意図的にハードコードされており、context_processors
オプションでオフにすることはできません。
各プロセッサは順番に適用されます。 つまり、1つのプロセッサがコンテキストに変数を追加し、2番目のプロセッサが同じ名前の変数を追加した場合、2番目のプロセッサが最初のプロセッサをオーバーライドします。 デフォルトのプロセッサについては、以下で説明します。
コンテキストプロセッサが適用される場合
コンテキストプロセッサは、コンテキストデータの上に適用されます。 つまり、コンテキストプロセッサは、 Context または RequestContext に指定した変数を上書きする可能性があるため、コンテキストプロセッサによって提供された変数名と重複しないように注意してください。
コンテキストデータをコンテキストプロセッサよりも優先する場合は、次のパターンを使用します。
from django.template import RequestContext
request_context = RequestContext(request)
request_context.push({"my_name": "Adrian"})
Djangoはこれを実行して、コンテキストデータが render()や TemplateResponse などのAPIのコンテキストプロセッサをオーバーライドできるようにします。
また、オプションの3番目の位置引数processors
を使用して、 RequestContext に追加のプロセッサのリストを指定できます。 この例では、 RequestContext インスタンスはip_address
変数を取得します。
from django.http import HttpResponse
from django.template import RequestContext, Template
def ip_address_processor(request):
return {'ip_address': request.META['REMOTE_ADDR']}
def client_ip_view(request):
template = Template('{{ title }}: {{ ip_address }}')
context = RequestContext(request, {
'title': 'Your IP Address',
}, [ip_address_processor])
return HttpResponse(template.render(context))
組み込みのテンプレートコンテキストプロセッサ
各組み込みプロセッサの機能は次のとおりです。
django.contrib.auth.context_processors.auth
- auth()
このプロセッサが有効になっている場合、すべてのRequestContext
には次の変数が含まれます。
user
–現在ログインしているユーザーを表すauth.User
インスタンス(または、クライアントがログインしていない場合はAnonymousUser
インスタンス)。perms
–django.contrib.auth.context_processors.PermWrapper
のインスタンスで、現在ログインしているユーザーが持っている権限を表します。
django.template.context_processors.debug
- debug()
このプロセッサが有効になっている場合、すべてのRequestContext
にはこれら2つの変数が含まれますが、:setting: `DEBUG` 設定がTrue
に設定され、リクエストのIPアドレスが設定されている場合に限ります。 (request.META['REMOTE_ADDR']
)は:setting: `INTERNAL_IPS` 設定にあります:
debug
–True
。 これをテンプレートで使用して、:setting: `DEBUG` モードであるかどうかをテストできます。sql_queries
–{'sql': ..., 'time': ...}
ディクショナリのリスト。リクエスト中にこれまでに発生したすべてのSQLクエリと、それにかかった時間を表します。 リストは、データベースエイリアス、クエリの順になっています。 アクセス時に遅延生成されます。
django.template.context_processors.i18n
- i18n()
このプロセッサが有効になっている場合、すべてのRequestContext
には次の変数が含まれます。
LANGUAGES
– :setting: `LANGUAGES` 設定の値。LANGUAGE_BIDI
–True
現在の言語が右から左の言語の場合、例: ヘブライ語、アラビア語。False
左から右の言語の場合、例: 英語、フランス語、ドイツ語。LANGUAGE_CODE
–request.LANGUAGE_CODE
(存在する場合)。 それ以外の場合は、:setting: `LANGUAGE_CODE` 設定の値。
同じ値を生成するテンプレートタグについては、 i18nテンプレートタグを参照してください。
django.template.context_processors.media
このプロセッサが有効になっている場合、すべてのRequestContext
には変数MEDIA_URL
が含まれ、:setting: `MEDIA_URL` 設定の値を提供します。
django.template.context_processors.static
- static()
このプロセッサが有効になっている場合、すべてのRequestContext
には変数STATIC_URL
が含まれ、:setting: `STATIC_URL` 設定の値を提供します。
django.template.context_processors.csrf
このプロセッサは、クロスサイトリクエストフォージェリから保護するために:ttag: `csrf_token` テンプレートタグに必要なトークンを追加します。
django.template.context_processors.request
このプロセッサが有効になっている場合、すべてのRequestContext
には、現在の HttpRequest である変数request
が含まれます。
django.template.context_processors.tz
- tz()
このプロセッサが有効になっている場合、すべてのRequestContext
には、現在アクティブなタイムゾーンの名前を提供する変数TIME_ZONE
が含まれます。
django.contrib.messages.context_processors.messages
このプロセッサが有効になっている場合、すべてのRequestContext
には次の2つの変数が含まれます。
messages
– メッセージフレームワークを介して設定されたメッセージのリスト(文字列として)。DEFAULT_MESSAGE_LEVELS
–メッセージレベル名のそれらの数値へのマッピング。
独自のコンテキストプロセッサを作成する
コンテキストプロセッサにはシンプルなインターフェイスがあります。これは、1つの引数 HttpRequest オブジェクトを受け取り、テンプレートコンテキストに追加される辞書を返すPython関数です。
たとえば、:setting: `DEFAULT_FROM_EMAIL` 設定をすべてのコンテキストに追加するには:
from django.conf import settings
def from_email(request):
return {
"DEFAULT_FROM_EMAIL": settings.DEFAULT_FROM_EMAIL,
}
カスタムコンテキストプロセッサは、コードベースのどこにでも存在できます。 Djangoが気にするのは、カスタムコンテキストプロセッサが:setting: `TEMPLATES` 設定の'context_processors'
オプション、またはのcontext_processors
引数によってポイントされることだけです。 ]直接使用している場合は。
テンプレートを読み込んでいます
通常、低レベルの Template APIを自分で使用するのではなく、ファイルシステム上のファイルにテンプレートを保存します。 テンプレートディレクトリとして指定されたディレクトリにテンプレートを保存します。
Djangoは、テンプレートの読み込み設定に応じて、さまざまな場所でテンプレートディレクトリを検索します(以下の「ローダーの種類」を参照)が、テンプレートディレクトリを指定する最も基本的な方法は、 :setting: `DIRS ` オプション。
NS :setting: `DIRS ` オプション
を使用して、テンプレートディレクトリが何であるかをDjangoに伝えます :setting: `DIRS ` のオプション :setting: `TEMPLATES` 設定ファイルでの設定—またはdirs
の引数エンジン 。 これは、テンプレートディレクトリへのフルパスを含む文字列のリストに設定する必要があります。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/home/html/templates/lawrence.com',
'/home/html/templates/default',
],
},
]
ディレクトリとテンプレートがWebサーバーで読み取り可能である限り、テンプレートはどこにでも移動できます。 .html
や.txt
など、任意の拡張子を付けることも、拡張子をまったく付けないこともできます。
これらのパスは、Windowsでも、Unixスタイルのスラッシュを使用する必要があることに注意してください。
ローダーの種類
デフォルトでは、Djangoはファイルシステムベースのテンプレートローダーを使用しますが、Djangoには他のソースからテンプレートをロードする方法を知っている他のいくつかのテンプレートローダーが付属しています。
これらの他のローダーの一部はデフォルトで無効になっていますが、:setting: `TEMPLATES` 設定のDjangoTemplates
バックエンドに'loaders'
オプションを追加するか、 loaders
引数を Engine に渡します。 loaders
は文字列またはタプルのリストである必要があり、それぞれがテンプレートローダークラスを表します。 Djangoに付属しているテンプレートローダーは次のとおりです。
django.template.loaders.filesystem.Loader
- class filesystem.Loader
に従って、ファイルシステムからテンプレートをロードします :setting: `DIRS ` 。
このローダーはデフォルトで有効になっています。 ただし、設定するまでテンプレートは見つかりません :setting: `DIRS ` 空でないリストへ:
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], }]
'DIRS'
をオーバーライドして、特定のファイルシステムローダーに特定のディレクトリを指定することもできます。TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ( 'django.template.loaders.filesystem.Loader', [BASE_DIR / 'templates'], ), ], }, }]
django.template.loaders.app_directories.Loader
- class app_directories.Loader
ファイルシステム上のDjangoアプリからテンプレートをロードします。 :setting: `INSTALLED_APPS` 内のアプリごとに、ローダーは
templates
サブディレクトリを探します。 ディレクトリが存在する場合、Djangoはそこでテンプレートを探します。これは、個々のアプリでテンプレートを保存できることを意味します。 これは、デフォルトのテンプレートを使用してDjangoアプリを配布するのにも役立ちます。
たとえば、この設定の場合:
INSTALLED_APPS = ['myproject.polls', 'myproject.music']
…次に、
get_template('foo.html')
はこれらのディレクトリでfoo.html
を次の順序で検索します。/path/to/myproject/polls/templates/
/path/to/myproject/music/templates/
…そして最初に見つけたものを使用します。
:setting: `INSTALLED_APPS` の順序は重要です! たとえば、Django管理者をカスタマイズする場合は、
django.contrib.admin
の標準のadmin/base_site.html
テンプレートを、myproject.polls
の独自のadmin/base_site.html
でオーバーライドすることを選択できます。 ]。 次に、myproject.polls
が:setting: `INSTALLED_APPS` のdjango.contrib.admin
の前に来ることを確認する必要があります。最初にロードされ、無視されます。ローダーは最初の実行時に最適化を実行することに注意してください。ローダーは、:setting: `INSTALLED_APPS` パッケージに
templates
サブディレクトリがあるリストをキャッシュします。このローダーを有効にするには、 :setting: `APP_DIRS ` に
True
:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, }]
django.template.loaders.cached.Loader
- class cached.Loader
デフォルトでは(:setting: `DEBUG` が
True
の場合)、テンプレートシステムは、テンプレートがレンダリングされるたびにテンプレートを読み取ってコンパイルします。 Djangoテンプレートシステムは非常に高速ですが、テンプレートの読み取りとコンパイルによるオーバーヘッドが増える可能性があります。キャッシュされたテンプレートローダーは、ラップする必要がある他のローダーのリストを使用して構成します。 ラップされたローダーは、未知のテンプレートが最初に検出されたときにそれらを見つけるために使用されます。 キャッシュされたローダーは、コンパイルされた
Template
をメモリに保存します。 キャッシュされたTemplate
インスタンスは、同じテンプレートをロードする後続のリクエストに対して返されます。このローダーは、次の場合に自動的に有効になります :setting: `OPTIONS ['loaders'] ` 指定されておらず、 :setting: `OPTIONS ['debug'] ` は
False
(後者のオプションのデフォルト値は :setting: `DEBUG` )。次のような設定を使用して、一部のカスタムテンプレートローダーでテンプレートキャッシュを有効にすることもできます。
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'OPTIONS': { 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', 'path.to.custom.Loader', ]), ], }, }]
ノート
組み込みのDjangoテンプレートタグはすべてキャッシュローダーで安全に使用できますが、サードパーティのパッケージからのカスタムテンプレートタグを使用している場合、または自分で作成した場合は、 [X218X ]各タグの実装はスレッドセーフです。 詳細については、テンプレートタグスレッドの安全性に関する考慮事項を参照してください。
django.template.loaders.locmem.Loader
- class locmem.Loader
Python辞書からテンプレートをロードします。 これはテストに役立ちます。
このローダーは、最初の引数としてテンプレートの辞書を取ります。
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ('django.template.loaders.locmem.Loader', { 'index.html': 'content here', }), ], }, }]
このローダーはデフォルトで無効になっています。
Djangoは、'loaders'
オプションに従ってテンプレートローダーを順番に使用します。 ローダーが一致するものを見つけるまで、各ローダーを使用します。
カスタムローダー
カスタムテンプレートローダーを使用して、追加のソースからテンプレートをロードすることができます。 カスタムLoader
クラスは、django.template.loaders.base.Loader
から継承し、get_contents()
およびget_template_sources()
メソッドを定義する必要があります。
ローダーメソッド
- class Loader
ファイルシステムやデータベースなどの特定のソースからテンプレートをロードします。
- get_template_sources(template_name)
template_name
を取得し、可能なソースごとに Origin インスタンスを生成するメソッド。たとえば、ファイルシステムローダーは
'index.html'
をtemplate_name
引数として受け取る場合があります。 このメソッドは、ローダーが参照する各テンプレートディレクトリに表示されるindex.html
のフルパスの起点を生成します。このメソッドは、テンプレートが特定のパスに存在することを確認する必要はありませんが、パスが有効であることを確認する必要があります。 たとえば、ファイルシステムローダーは、パスが有効なテンプレートディレクトリの下にあることを確認します。
- get_contents(origin)
Origin インスタンスを指定してテンプレートのコンテンツを返します。
これは、ファイルシステムローダーがファイルシステムからコンテンツを読み取る場所、またはデータベースローダーがデータベースから読み取る場所です。 一致するテンプレートが存在しない場合、 TemplateDoesNotExist エラーが発生するはずです。
- get_template(template_name, skip=None)
get_template_sources()の結果をループし、 get_contents()を呼び出すことにより、指定された
template_name
のTemplate
オブジェクトを返します。 これにより、最初に一致するテンプレートが返されます。 テンプレートが見つからない場合は、 TemplateDoesNotExist が発生します。オプションの
skip
引数は、テンプレートを拡張するときに無視する起点のリストです。 これにより、テンプレートは同じ名前の他のテンプレートを拡張できます。 また、再帰エラーを回避するためにも使用されていました。一般に、カスタムテンプレートローダーには get_template_sources()と get_contents()を定義するだけで十分です。
get_template()
は通常、オーバーライドする必要はありません。
テンプレートの起源
テンプレートには、ロード元に応じた属性を含むorigin
があります。
- class Origin(name, template_name=None, loader=None)
- name
テンプレートローダーによって返されるテンプレートへのパス。 ファイルシステムから読み取るローダーの場合、これはテンプレートへのフルパスです。
テンプレートがテンプレートローダーを介してではなく直接インスタンス化される場合、これは
<unknown_source>
の文字列値です。
- template_name
テンプレートローダーに渡されるテンプレートへの相対パス。
テンプレートがテンプレートローダーを介してではなく直接インスタンス化される場合、これは
None
です。
- loader
この
Origin
を構築したテンプレートローダーインスタンス。テンプレートがテンプレートローダーを介してではなく直接インスタンス化される場合、これは
None
です。django.template.loaders.cached.Loader では、通常、
Origin
をloader=self
でインスタンス化することにより、ラップされたすべてのローダーでこの属性を設定する必要があります。