テンプレート
WebフレームワークであるDjangoには、HTMLを動的に生成するための便利な方法が必要です。 最も一般的なアプローチはテンプレートに依存しています。 テンプレートには、目的のHTML出力の静的部分と、動的コンテンツの挿入方法を説明する特別な構文が含まれています。 テンプレートを使用してHTMLページを作成する実践的な例については、チュートリアル3 を参照してください。
Djangoプロジェクトは、1つまたは複数のテンプレートエンジンで構成できます(テンプレートを使用しない場合はゼロでも構成できます)。 Djangoには、Djangoテンプレート言語(DTL)と呼ばれる独自のテンプレートシステムと、人気のある代替 Jinja2 用の組み込みバックエンドが付属しています。 他のテンプレート言語のバックエンドは、サードパーティから入手できる場合があります。 独自のカスタムバックエンドを作成することもできます。カスタムテンプレートバックエンドを参照してください。
Djangoは、バックエンドに関係なく、テンプレートを読み込んでレンダリングするための標準APIを定義しています。 ロードは、特定の識別子のテンプレートを見つけて前処理し、通常はメモリ内の表現にコンパイルすることで構成されます。 レンダリングとは、テンプレートをコンテキストデータで補間し、結果の文字列を返すことを意味します。
Djangoテンプレート言語は、Django独自のテンプレートシステムです。 Django 1.8までは、利用可能な唯一の組み込みオプションでした。 それはかなり意見があり、いくつかの特異性を誇っていますが、それは良いテンプレートライブラリです。 別のバックエンドを選択する差し迫った理由がない場合、特にプラグイン可能なアプリケーションを作成していて、テンプレートを配布する予定がある場合は、DTLを使用する必要があります。 django.contrib.admin などのテンプレートを含むDjangoのcontribアプリは、DTLを使用します。
歴史的な理由から、テンプレートエンジンの一般的なサポートとDjangoテンプレート言語の実装の両方がdjango.template
名前空間に存在します。
警告
テンプレートシステムは、信頼できないテンプレート作成者に対して安全ではありません。 たとえば、テンプレートの作成者はXSS攻撃を実行したり、機密情報を含む可能性のあるテンプレート変数のプロパティにアクセスしたりできるため、サイトはユーザーが独自のテンプレートを提供することを許可しないでください。
Djangoテンプレート言語
構文
Djangoテンプレートは、Djangoテンプレート言語を使用してマークアップされたテキストドキュメントまたはPython文字列です。 一部の構成は、テンプレートエンジンによって認識および解釈されます。 主なものは変数とタグです。
テンプレートはコンテキストでレンダリングされます。 レンダリングは、変数をコンテキストで検索される値に置き換え、タグを実行します。 それ以外はすべてそのまま出力されます。
Djangoテンプレート言語の構文には、4つの構成要素が含まれます。
変数
変数は、コンテキストから値を出力します。これは、キーを値にマッピングするdictのようなオブジェクトです。
変数は、次のように{{
と}}
で囲まれています。
My first name is {{ first_name }}. My last name is {{ last_name }}.
{'first_name': 'John', 'last_name': 'Doe'}
のコンテキストでは、このテンプレートは次のようにレンダリングされます。
My first name is John. My last name is Doe.
ディクショナリルックアップ、属性ルックアップ、およびリストインデックスルックアップは、ドット表記で実装されています。
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}
変数が呼び出し可能変数に解決される場合、テンプレートシステムは引数なしで変数を呼び出し、呼び出し可能変数の代わりにその結果を使用します。
フィルタ
フィルタは、変数とタグ引数の値を変換します。
彼らはこのように見えます:
{{ django|title }}
{'django': 'the web framework for perfectionists with deadlines'}
のコンテキストでは、このテンプレートは次のようにレンダリングされます。
The Web Framework For Perfectionists With Deadlines
一部のフィルターには引数があります。
{{ my_date|date:"Y-m-d" }}
組み込みフィルターのリファレンスと、カスタムフィルターの作成手順を利用できます。
コンポーネント
エンジン
django.template.Engine は、Djangoテンプレートシステムのインスタンスをカプセル化します。 Engine を直接インスタンス化する主な理由は、Djangoプロジェクトの外部でDjangoテンプレート言語を使用するためです。
django.template.backends.django.DjangoTemplates は、 django.template.Engine をDjangoのテンプレートバックエンドAPIに適合させる薄いラッパーです。
レンプレート
django.template.Template は、コンパイルされたテンプレートを表します。 テンプレートは、 Engine.get_template()または Engine.from_string()で取得されます。
同様に、django.template.backends.django.Template
は、 django.template.Template を共通のテンプレートAPIに適合させる薄いラッパーです。
環境
django.template.Context は、コンテキストデータに加えていくつかのメタデータを保持します。 テンプレートをレンダリングするために Template.render()に渡されます。
django.template.RequestContext は、現在の HttpRequest を格納し、テンプレートコンテキストプロセッサを実行する Context のサブクラスです。
一般的なAPIには同等の概念がありません。 コンテキストデータはプレーンなdict
で渡され、現在の HttpRequest は必要に応じて個別に渡されます。
ローダー
テンプレートローダーは、テンプレートの検索、ロード、および Template オブジェクトの返却を担当します。
Djangoはいくつかの組み込みテンプレートローダーを提供し、カスタムテンプレートローダーをサポートします。
コンテキストプロセッサ
コンテキストプロセッサは、現在の HttpRequest を引数として受け取り、レンダリングコンテキストに追加されるデータのdict
を返す関数です。
それらの主な用途は、すべてのビューでコードを繰り返すことなく、すべてのテンプレートで共有される共通データをコンテキストに追加することです。
Djangoは多くの組み込みコンテキストプロセッサを提供しており、独自の追加コンテキストプロセッサを実装することもできます。
テンプレートエンジンのサポート
構成
テンプレートエンジンは、:setting: `TEMPLATES` 設定で構成されます。 これは、エンジンごとに1つずつ、構成のリストです。 デフォルト値は空です。 :djadmin: `startproject` コマンドによって生成されたsettings.py
は、より有用な値を定義します。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
},
]
:setting: `バックエンド ` DjangoのテンプレートバックエンドAPIを実装するテンプレートエンジンクラスへの点線のPythonパスです。 組み込みのバックエンドは、 django.template.backends.django.DjangoTemplates と django.template.backends.jinja2.Jinja2 です。
ほとんどのエンジンはファイルからテンプレートをロードするため、各エンジンの最上位構成には2つの一般的な設定が含まれています。
- :setting: `DIRS ` エンジンがテンプレートソースファイルを検索するディレクトリのリストを検索順に定義します。
- :setting: `APP_DIRS ` エンジンがインストールされたアプリケーション内のテンプレートを探す必要があるかどうかを示します。 各バックエンドは、テンプレートを保存するアプリケーション内のサブディレクトリの従来の名前を定義します。
まれですが、同じバックエンドの複数のインスタンスを異なるオプションで構成することは可能です。 その場合、一意を定義する必要があります :setting: `NAME ` エンジンごとに。
:setting: `オプション ` バックエンド固有の設定が含まれています。
使用法
django.template.loader
モジュールは、テンプレートをロードするための2つの関数を定義します。
- get_template(template_name, using=None)
この関数は、指定された名前のテンプレートをロードし、
Template
オブジェクトを返します。戻り値の正確なタイプは、テンプレートをロードしたバックエンドによって異なります。 各バックエンドには、独自の
Template
クラスがあります。get_template()
は、成功するまで各テンプレートエンジンを順番に試行します。 テンプレートが見つからない場合は、 TemplateDoesNotExist が発生します。 テンプレートが見つかったが無効な構文が含まれている場合、 TemplateSyntaxError が発生します。テンプレートの検索方法とロード方法は、各エンジンのバックエンドと構成によって異なります。
検索を特定のテンプレートエンジンに制限する場合は、エンジンの :setting: `NAME ` の中に
using
口論。
- select_template(template_name_list, using=None)
select_template()
はget_template()
と同じですが、テンプレート名のリストを取得する点が異なります。 それぞれの名前を順番に試し、存在する最初のテンプレートを返します。
テンプレートのロードに失敗した場合、django.template
で定義されている次の2つの例外が発生する可能性があります。
- exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)
- この例外は、テンプレートが見つからない場合に発生します。 デバッグページで template postmortem を設定するために、次のオプションの引数を受け入れます。
backend
- 例外が発生したテンプレートバックエンドインスタンス。
tried
- テンプレートを見つけるときに試行されたソースのリスト。 これは、
(origin, status)
を含むタプルのリストとしてフォーマットされます。ここで、origin
は origin-like オブジェクトであり、status
はテンプレートの理由を含む文字列です。見つかりませんでした。 chain
- テンプレートを読み込もうとしたときに発生した中間の TemplateDoesNotExist 例外のリスト。 これは、 get_template()など、複数のエンジンから特定のテンプレートを読み込もうとする関数によって使用されます。
- exception TemplateSyntaxError(msg)
- この例外は、テンプレートが見つかったがエラーが含まれている場合に発生します。
get_template()
およびselect_template()
によって返されるTemplate
オブジェクトは、render()
メソッドに次の署名を提供する必要があります。
- Template.render(context=None, request=None)
指定されたコンテキストでこのテンプレートをレンダリングします。
context
を指定する場合は、dict
である必要があります。 提供されていない場合、エンジンは空のコンテキストでテンプレートをレンダリングします。request
を指定する場合は、 HttpRequest である必要があります。 次に、エンジンはそれとCSRFトークンをテンプレートで使用できるようにする必要があります。 これをどのように達成するかは、各バックエンド次第です。
これが検索アルゴリズムの例です。 この例では、:setting: `TEMPLATES` 設定は次のとおりです。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/home/html/example.com',
'/home/html/default',
],
},
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [
'/home/html/jinja2',
],
},
]
get_template('story_detail.html')
を呼び出すと、Djangoが検索するファイルが順番に表示されます。
/home/html/example.com/story_detail.html
('django'
エンジン)/home/html/default/story_detail.html
('django'
エンジン)/home/html/jinja2/story_detail.html
('jinja2'
エンジン)
select_template(['story_253_detail.html', 'story_detail.html'])
を呼び出すと、Djangoが検索するものは次のとおりです。
/home/html/example.com/story_253_detail.html
('django'
エンジン)/home/html/default/story_253_detail.html
('django'
エンジン)/home/html/jinja2/story_253_detail.html
('jinja2'
エンジン)/home/html/example.com/story_detail.html
('django'
エンジン)/home/html/default/story_detail.html
('django'
エンジン)/home/html/jinja2/story_detail.html
('jinja2'
エンジン)
Djangoが存在するテンプレートを見つけると、検索を停止します。
ヒント
select_template()を使用して、柔軟なテンプレートの読み込みを行うことができます。 たとえば、ニュース記事を作成していて、一部の記事にカスタムテンプレートを設定したい場合は、select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])
のようなものを使用します。 これにより、個々のストーリーにカスタムテンプレートを使用し、カスタムテンプレートを持たないストーリーにフォールバックテンプレートを使用できるようになります。
テンプレートを含む各ディレクトリ内のサブディレクトリにテンプレートを整理することは可能であり、望ましいことです。 慣例では、Djangoアプリごとにサブディレクトリを作成し、必要に応じてそれらのサブディレクトリ内にサブディレクトリを作成します。
あなた自身の正気のためにこれをしてください。 すべてのテンプレートを単一のディレクトリのルートレベルに保存すると、面倒になります。
サブディレクトリ内にあるテンプレートをロードするには、次のようにスラッシュを使用します。
get_template('news/story_detail.html')
上記と同じ:setting: `TEMPLATES` オプションを使用して、次のテンプレートをロードしようとします。
/home/html/example.com/news/story_detail.html
('django'
エンジン)/home/html/default/news/story_detail.html
('django'
エンジン)/home/html/jinja2/news/story_detail.html
('jinja2'
エンジン)
さらに、テンプレートの読み込みとレンダリングの繰り返しの性質を減らすために、Djangoはプロセスを自動化するショートカット機能を提供します。
- render_to_string(template_name, context=None, request=None, using=None)
render_to_string()
は、 get_template()のようなテンプレートをロードし、そのrender()
メソッドをすぐに呼び出します。 次の引数を取ります。template_name
ロードしてレンダリングするテンプレートの名前。 テンプレート名のリストの場合、Djangoは get_template()ではなく select_template()を使用してテンプレートを検索します。
context
レンダリング用のテンプレートのコンテキストとして使用される
dict
。request
テンプレートのレンダリングプロセス中に使用できるオプションの HttpRequest 。
using
オプションのテンプレートエンジン :setting: `NAME ` 。 テンプレートの検索は、そのエンジンに制限されます。
使用例:
from django.template.loader import render_to_string rendered = render_to_string('my_template.html', {'foo': 'bar'})
render_to_string()を呼び出し、ビューから戻るのに適した HttpResponse に結果をフィードする render()ショートカットも参照してください。
最後に、構成済みのエンジンを直接使用できます。
- engines
テンプレートエンジンは
django.template.engines
で利用できます。from django.template import engines django_engine = engines['django'] template = django_engine.from_string("Hello {{ name }}!")
ルックアップキー—
'django'
この例では—はエンジンの :setting: `NAME ` 。
組み込みのバックエンド
- class DjangoTemplates
設定 :setting: `バックエンド ` に'django.template.backends.django.DjangoTemplates'
Djangoテンプレートエンジンを構成します。
いつ :setting: `APP_DIRS ` はTrue
、DjangoTemplates
エンジンはでテンプレートを探しますtemplates
インストールされているアプリケーションのサブディレクトリ。 この一般名は、下位互換性のために保持されています。
DjangoTemplates
エンジンは以下を受け入れます :setting: `オプション ` :
'autoescape'
:HTML自動エスケープを有効にするかどうかを制御するブール値。デフォルトは
True
です。警告
HTML以外のテンプレートをレンダリングする場合にのみ、
False
に設定してください。'context_processors'
:テンプレートがリクエストでレンダリングされるときにコンテキストにデータを入力するために使用される呼び出し可能オブジェクトへの点線のPythonパスのリスト。 これらの呼び出し可能オブジェクトは、引数として要求オブジェクトを受け取り、コンテキストにマージされるアイテムのdict
を返します。デフォルトでは空のリストになります。
詳細については、 RequestContext を参照してください。
'debug'
:テンプレートデバッグモードをオン/オフにするブール値。True
の場合、ファンシーエラーページには、テンプレートのレンダリング中に発生した例外の詳細レポートが表示されます。 このレポートには、適切な行が強調表示されたテンプレートの関連スニペットが含まれています。デフォルトでは、:setting: `DEBUG` 設定の値になります。
'loaders'
:テンプレートローダークラスへの点線のPythonパスのリスト。 各Loader
クラスは、特定のソースからテンプレートをインポートする方法を知っています。 オプションで、文字列の代わりにタプルを使用できます。 タプルの最初の項目はLoader
クラス名である必要があり、後続の項目は初期化中にLoader
に渡されます。デフォルトはの値によって異なります :setting: `DIRS ` と :setting: `APP_DIRS ` 。
詳細については、ローダータイプを参照してください。
'string_if_invalid'
:テンプレートシステムが無効に使用する必要がある文字列としての出力(例: スペルミス)変数。デフォルトは空の文字列です。
詳細については、無効な変数の処理方法を参照してください。
'file_charset'
:ディスク上のテンプレートファイルを読み取るために使用される文字セット。デフォルトは
'utf-8'
です。'libraries'
:テンプレートエンジンに登録するためのテンプレートタグモジュールのラベルと点線のPythonパスの辞書。 これを使用して、新しいライブラリを追加したり、既存のライブラリの代替ラベルを提供したりできます。 例えば:OPTIONS={ 'libraries': { 'myapp_tags': 'path.to.myapp.tags', 'admin.urls': 'django.contrib.admin.templatetags.admin_urls', }, }
ライブラリは、対応する辞書キーをに渡すことでロードできます。 :ttag: `{%load%} ` 鬼ごっこ。
'builtins'
:ビルトインに追加するテンプレートタグモジュールの点線のPythonパスのリスト。 例えば:OPTIONS={ 'builtins': ['myapp.builtins'], }
組み込みライブラリのタグとフィルタは、最初にを呼び出さなくても使用できます。 :ttag: `{%load%} ` 鬼ごっこ。
- class Jinja2
Jinja2 がインストールされている必要があります。
設定 :setting: `バックエンド ` に'django.template.backends.jinja2.Jinja2'
を構成するには Jinja2 エンジン。
いつ :setting: `APP_DIRS ` はTrue
、Jinja2
エンジンはでテンプレートを探しますjinja2
インストールされているアプリケーションのサブディレクトリ。
の最も重要なエントリ :setting: `オプション ` は'environment'
。 これは、Jinja2環境を返す呼び出し可能オブジェクトへの点線のPythonパスです。 デフォルトは'jinja2.Environment'
です。 Djangoはその呼び出し可能オブジェクトを呼び出し、他のオプションをキーワード引数として渡します。 さらに、Djangoは、いくつかのオプションについてJinja2とは異なるデフォルトを追加します。
'autoescape'
:True
'loader'
:用に構成されたローダー :setting: `DIRS ` と :setting: `APP_DIRS `'auto_reload'
:settings.DEBUG
'undefined'
:DebugUndefined if settings.DEBUG else Undefined
Jinja2
エンジンは以下も受け入れます :setting: `オプション ` :
'context_processors'
:テンプレートがリクエストでレンダリングされるときにコンテキストにデータを入力するために使用される呼び出し可能オブジェクトへの点線のPythonパスのリスト。 これらの呼び出し可能オブジェクトは、引数として要求オブジェクトを受け取り、コンテキストにマージされるアイテムのdict
を返します。デフォルトでは空のリストになります。
Jinja2テンプレートでコンテキストプロセッサを使用することはお勧めしません。
Djangoテンプレートは引数を使用した関数の呼び出しをサポートしていないため、コンテキストプロセッサはDjangoテンプレートで役立ちます。 Jinja2にはその制限がないため、以下に説明するように、
jinja2.Environment
を使用してテンプレートで使用可能なグローバル変数にコンテキストプロセッサとして使用する関数を配置することをお勧めします。 次に、テンプレートでその関数を呼び出すことができます。{{ function(request) }}
一部のDjangoテンプレートコンテキストプロセッサは固定値を返します。 Jinja2テンプレートの場合、
jinja2.Environment
に定数を直接追加できるため、この間接層は必要ありません。Jinja2のコンテキストプロセッサを追加するための元のユースケースは次のとおりです。
要求に応じてコストのかかる計算を行う。
すべてのテンプレートで結果が必要です。
各テンプレートで結果を複数回使用する。
これらの条件がすべて満たされていない限り、関数をテンプレートに渡すことは、Jinja2の設計とより一致しています。
デフォルト設定は意図的に最小限に抑えられています。 テンプレートがリクエストでレンダリングされる場合(例: render())を使用する場合、Jinja2
バックエンドは、グローバルrequest
、csrf_input
、およびcsrf_token
をコンテキストに追加します。 それとは別に、このバックエンドはDjangoフレーバーの環境を作成しません。 Djangoのフィルターとタグについては知りません。 Django固有のAPIを使用するには、それらを環境に構成する必要があります。
たとえば、次のコンテンツを使用してmyproject/jinja2.py
を作成できます。
from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update({
'static': static,
'url': reverse,
})
return env
'environment'
オプションを'myproject.jinja2.environment'
に設定します。
次に、Jinja2テンプレートで次の構成を使用できます。
<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">
<a href="{{ url('admin:index') }}">Administration</a>
タグとフィルターの概念は、Djangoテンプレート言語とJinja2の両方に存在しますが、使用方法は異なります。 Jinja2はテンプレート内の呼び出し可能オブジェクトへの引数の受け渡しをサポートしているため、上記の例に示すように、Djangoテンプレート内の関数を呼び出すことでテンプレートタグまたはDjangoテンプレート内のフィルターを必要とする多くの機能を実現できます。 Jinja2のグローバル名前空間により、テンプレートコンテキストプロセッサが不要になります。 Djangoテンプレート言語には、Jinja2テストに相当するものがありません。
コメント
コメントは次のようになります。
NS :ttag: `{%コメント%} ` タグは複数行のコメントを提供します。