Djangoテンプレート言語:Pythonプログラマー向け—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/templates/api
移動先:案内検索

Djangoテンプレート言語:Pythonプログラマー向け

このドキュメントでは、Djangoテンプレートシステムを技術的な観点から説明します–それがどのように機能し、どのように拡張するか。 言語構文のリファレンスを探している場合は、 Djangoテンプレート言語を参照してください。

テンプレート、コンテキスト、変数、タグ、およびレンダリングについて理解していることを前提としています。 これらの概念に慣れていない場合は、 Djangoテンプレート言語の概要から始めてください。

概要

Pythonでテンプレートシステムを使用することは、3つのステップのプロセスです。

  1. エンジンを構成します。
  2. テンプレートコードをテンプレートにコンパイルします。
  3. コンテキストを使用してテンプレートをレンダリングします。

Djangoプロジェクトは通常、テンプレートシステムの低レベルAPIではなく、これらの各ステップで高レベルのバックエンドに依存しないAPI に依存しています。

  1. :setting: `TEMPLATES` 設定の DjangoTemplates バックエンドごとに、Djangoは Engine をインスタンス化します。 DjangoTemplates は、 Engine をラップし、それを共通のテンプレートバックエンドAPIに適合させます。
  2. django.template.loader モジュールは、テンプレートをロードするための get_template()などの関数を提供します。 それらは、実際の django.template.Template をラップするdjango.template.backends.django.Templateを返します。
  3. 前のステップで取得した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_dirsTrueである場合に限ります。

    debugFalseの場合、これらのローダーは 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が他の値に設定されている場合、変数フィルターは無視されます。

この動作は、iffor、およびregroupテンプレートタグではわずかに異なります。 これらのテンプレートタグの1つに無効な変数が指定された場合、その変数はNoneとして解釈されます。 フィルタは、これらのテンプレートタグ内の無効な変数に常に適用されます。

string_if_invalid'%s'が含まれている場合、フォーマットマーカーは無効な変数の名前に置き換えられます。

デバッグのみを目的としています。

string_if_invalidは便利なデバッグツールですが、「開発のデフォルト」としてオンにすることはお勧めできません。

一部のDjangoを含む多くのテンプレートは、存在しない変数が検出された場合のテンプレートシステムの無音に依存しています。 以外の値をstring_if_invalidに割り当てると、これらのテンプレートとサイトでレンダリングの問題が発生します。

通常、string_if_invalidは、特定のテンプレートの問題をデバッグするためにのみ有効にし、デバッグが完了したらクリアする必要があります。


組み込み変数

すべてのコンテキストには、TrueFalse、および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がコンテキスト内にある場合、その値を返します。 それ以外の場合は、値がdefaultkeyを挿入し、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()の結果は、Contextdictと比較する単体テストで役立ちます。

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インスタンス)。
  • permsdjango.contrib.auth.context_processors.PermWrapperのインスタンスで、現在ログインしているユーザーが持っている権限を表します。


django.template.context_processors.debug

debug()

このプロセッサが有効になっている場合、すべてのRequestContextにはこれら2つの変数が含まれますが、:setting: `DEBUG` 設定がTrueに設定され、リクエストのIPアドレスが設定されている場合に限ります。 (request.META['REMOTE_ADDR'])は:setting: `INTERNAL_IPS` 設定にあります:

  • debugTrue。 これをテンプレートで使用して、:setting: `DEBUG` モードであるかどうかをテストできます。
  • sql_queries{'sql': ..., 'time': ...}ディクショナリのリスト。リクエスト中にこれまでに発生したすべてのSQLクエリと、それにかかった時間を表します。 リストは、データベースエイリアス、クエリの順になっています。 アクセス時に遅延生成されます。


django.template.context_processors.i18n

i18n()

このプロセッサが有効になっている場合、すべてのRequestContextには次の変数が含まれます。

  • LANGUAGES:setting: `LANGUAGES` 設定の値。
  • LANGUAGE_BIDITrue現在の言語が右から左の言語の場合、例: ヘブライ語、アラビア語。 False左から右の言語の場合、例: 英語、フランス語、ドイツ語。
  • LANGUAGE_CODErequest.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つの変数が含まれます。


独自のコンテキストプロセッサを作成する

コンテキストプロセッサにはシンプルなインターフェイスがあります。これは、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_nameTemplateオブジェクトを返します。 これにより、最初に一致するテンプレートが返されます。 テンプレートが見つからない場合は、 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 では、通常、Originloader=selfでインスタンス化することにより、ラップされたすべてのローダーでこの属性を設定する必要があります。