The Django Template Language¶
このドキュメントはDjangoテンプレートシステムの文法を説明しています。もしあなたがもっと技術者的な観点でどう動かすかやどう拡張するかを知りたい場合は、The Django template language: for Python programmers をご覧ください。
Django のテンプレート言語は、パワーと使いやすさのバランスを取るように設計されています。HTMLでの作業に使用されるものが快適に感じられるように設計されているのです。あなたが他のテキストベースのテンプレート言語に対して Smarty や Jinja2 のような露出的な処理を習得しているのなら、Django テンプレートをより身近に感じられるはずです。
設計思想
あなたがどんなプログラミング経験を持ってるにしろ、HTMLの中にコードを埋め込む言語を使っていたにしろ、DjangoテンプレートシステムはただHTMLのなかにPythonを貼り付けるだけのシステムではないことを心に留めたいと思われたでしょう。これは"テンプレートシステムは、プログラム論理構造を表すのでなく、あくまでプレゼンテーションを表現することを意味する。"というデザイン設計から来ています。
Django のテンプレートシステムは、いくつかのプログラミング構造 - ブールテスト用の if
タグ、ループ用の for
タグなどと同様に機能するタグを提供しています。しかしこれらは、単純に対応する Python コードとしては実行するわけではなく、テンプレートシステムは、任意の Python の式を実行しません。タグ、フィルタ、および下の文法リストのみがデフォルトではサポートされています。(しかし、必要に応じて あなた独自の拡張機能 をテンプレート言語に追加することも可能です。)
テンプレート¶
テンプレートは、単純なテキストファイルです。これは、任意のテキストベースのフォーマット (HTML、XML、CSV) などを生成することができます。
テンプレートに含まれるのは、テンプレートが読み込まれたとき実際の値で置き換えられる 変数 と、テンプレートのロジックを制御する タグ です。
下は幾つかの基本を示している少ない見本です。各要素については、このドキュメントの後半で説明します。
{% extends "base_generic.html" %}
{% block title %}{{ section.title }}{% endblock %}
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
設計思想
なぜ、(ZopeのTALのような) XMLベースのテンプレートではなく、テキストベースのテンプレートを使うのか?それは、Django のテンプレート言語を XML/ HTML テンプレートより使いやすくしたかったからです。ワールドオンラインでは、我々は E メールや JavaScript、CSV のためにそれを使用しています。テンプレート言語は、どんなテキストベースのフォーマットにも使うことができます。
ああ、それともう一つ: 人間にXMLを編集させることは非常に酷なことです!
変数¶
変数は次のような見た目です: {{ variable }}
。テンプレートエンジンが変数を検出すると、その変数を認識し、その結果に置き換えます。変数名は、英数字の任意の組み合わせとアンダースコア ("_"
) で構成されています。ドット ("."
) も変数セクションに表示されますが、以下に示すように特別な意味を持っています。重要なのは、変数名にスペースまたは句読点を持つことはできない ということです。
変数の属性にアクセスするには、ドットを ('.
') を使用します。
背景
技術的には、テンプレートシステムがドットを検出した際、以下の参照項目をこの順番で実行しようとします:
- 辞書検索
- 属性やメソッドの検索
- 数値のインデックス検索
結果の値が呼び出し可能である場合は、引数なしで呼び出されます。呼び出しの結果は、テンプレートの値となります。
この検索の手順は、辞書検索を上書きするオブジェクトにおいて、予期しない動作を引き起こす可能性があります。例えば、`` collections.defaultdict`` すべてをループ処理をしようとする、次のコードスニペットを考えてみましょう:
{% for k, v in defaultdict.items %}
Do something with k and v here...
{% endfor %}
最初に辞書検索が行われるため、その挙動が動作してしまい、意図していた ``.items()``メソッドを使用せずに、デフォルト値を提供してしまいます。この場合、最初に辞書を変換することを検討してください。
In the above example, {{ section.title }}
will be replaced with the
title
attribute of the section
object.
もし存在しない変数を使いたい場合、テンプレートシステムは`デフォルトで``''`` (the empty string)が置かれている場所に、string_if_invalid` のオプション値を挿入します。
Note that "bar" in a template expression like {{ foo.bar }}
will be
interpreted as a literal string and not using the value of the variable "bar",
if one exists in the template context.
フィルター¶
You can modify variables for display by using filters.
Filters look like this: {{ name|lower }}
. This displays the value of the
{{ name }}
variable after being filtered through the lower
filter, which converts text to lowercase. Use a pipe (|
) to apply a filter.
Filters can be "chained." The output of one filter is applied to the next.
{{ text|escape|linebreaks }}
is a common idiom for escaping text contents,
then converting line breaks to <p>
tags.
Some filters take arguments. A filter argument looks like this: {{
bio|truncatewords:30 }}
. This will display the first 30 words of the bio
variable.
Filter arguments that contain spaces must be quoted; for example, to join a
list with commas and spaces you'd use {{ list|join:", " }}
.
Django provides about sixty built-in template filters. You can read all about them in the built-in filter reference. To give you a taste of what's available, here are some of the more commonly used template filters:
default
If a variable is false or empty, use given default. Otherwise, use the value of the variable. For example:
{{ value|default:"nothing" }}
If
value
isn't provided or is empty, the above will display "nothing
".length
Returns the length of the value. This works for both strings and lists. For example:
{{ value|length }}
If
value
is['a', 'b', 'c', 'd']
, the output will be4
.filesizeformat
Formats the value like a "human-readable" file size (i.e.
'13 KB'
,'4.1 MB'
,'102 bytes'
, etc.). For example:{{ value|filesizeformat }}
value
が 123456789 のとき、出力は117.7 MB
になります。
Again, these are just a few examples; see the built-in filter reference for the complete list.
You can also create your own custom template filters; see 独自のテンプレートタグとフィルタ.
参考
Django's admin interface can include a complete reference of all template tags and filters available for a given site. See The Django admin documentation generator.
タグ¶
Tags look like this: {% tag %}
. Tags are more complex than variables: Some
create text in the output, some control flow by performing loops or logic, and
some load external information into the template to be used by later variables.
Some tags require beginning and ending tags (i.e. {% tag %} ... tag contents
... {% endtag %}
).
Django ships with about two dozen built-in template tags. You can read all about them in the built-in tag reference. To give you a taste of what's available, here are some of the more commonly used tags:
for
Loop over each item in an array. For example, to display a list of athletes provided in
athlete_list
:<ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
if
,elif
, andelse
Evaluates a variable, and if that variable is "true" the contents of the block are displayed:
{% if athlete_list %} Number of athletes: {{ athlete_list|length }} {% elif athlete_in_locker_room_list %} Athletes should be out of the locker room soon! {% else %} No athletes. {% endif %}
In the above, if
athlete_list
is not empty, the number of athletes will be displayed by the{{ athlete_list|length }}
variable. Otherwise, ifathlete_in_locker_room_list
is not empty, the message "Athletes should be out..." will be displayed. If both lists are empty, "No athletes." will be displayed.You can also use filters and various operators in the
if
tag:{% if athlete_list|length > 1 %} Team: {% for athlete in athlete_list %} ... {% endfor %} {% else %} Athlete: {{ athlete_list.0.name }} {% endif %}
While the above example works, be aware that most template filters return strings, so mathematical comparisons using filters will generally not work as you expect.
length
is an exception.block
andextends
- Set up template inheritance (see below), a powerful way of cutting down on "boilerplate" in templates.
Again, the above is only a selection of the whole list; see the built-in tag reference for the complete list.
You can also create your own custom template tags; see 独自のテンプレートタグとフィルタ.
参考
Django's admin interface can include a complete reference of all template tags and filters available for a given site. See The Django admin documentation generator.
コメント¶
To comment-out part of a line in a template, use the comment syntax: {# #}
.
For example, this template would render as 'hello'
:
{# greeting #}hello
A comment can contain any template code, invalid or not. For example:
{# {% if foo %}bar{% else %} #}
This syntax can only be used for single-line comments (no newlines are permitted
between the {#
and #}
delimiters). If you need to comment out a
multiline portion of the template, see the comment
tag.
Template inheritance¶
The most powerful -- and thus the most complex -- part of Django's template engine is template inheritance. Template inheritance allows you to build a base "skeleton" template that contains all the common elements of your site and defines blocks that child templates can override.
It's easiest to understand template inheritance by starting with an example:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
This template, which we'll call base.html
, defines a simple HTML skeleton
document that you might use for a simple two-column page. It's the job of
"child" templates to fill the empty blocks with content.
In this example, the block
tag defines three blocks that child
templates can fill in. All the block
tag does is to tell the template
engine that a child template may override those portions of the template.
A child template might look like this:
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
The extends
tag is the key here. It tells the template engine that
this template "extends" another template. When the template system evaluates
this template, first it locates the parent -- in this case, "base.html".
At that point, the template engine will notice the three block
tags
in base.html
and replace those blocks with the contents of the child
template. Depending on the value of blog_entries
, the output might look
like:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>My amazing blog</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div>
<div id="content">
<h2>Entry one</h2>
<p>This is my first entry.</p>
<h2>Entry two</h2>
<p>This is my second entry.</p>
</div>
</body>
</html>
Note that since the child template didn't define the sidebar
block, the
value from the parent template is used instead. Content within a {% block %}
tag in a parent template is always used as a fallback.
You can use as many levels of inheritance as needed. One common way of using inheritance is the following three-level approach:
- Create a
base.html
template that holds the main look-and-feel of your site. - Create a
base_SECTIONNAME.html
template for each "section" of your site. For example,base_news.html
,base_sports.html
. These templates all extendbase.html
and include section-specific styles/design. - Create individual templates for each type of page, such as a news article or blog entry. These templates extend the appropriate section template.
This approach maximizes code reuse and makes it easy to add items to shared content areas, such as section-wide navigation.
Here are some tips for working with inheritance:
If you use
{% extends %}
in a template, it must be the first template tag in that template. Template inheritance won't work, otherwise.More
{% block %}
tags in your base templates are better. Remember, child templates don't have to define all parent blocks, so you can fill in reasonable defaults in a number of blocks, then only define the ones you need later. It's better to have more hooks than fewer hooks.If you find yourself duplicating content in a number of templates, it probably means you should move that content to a
{% block %}
in a parent template.If you need to get the content of the block from the parent template, the
{{ block.super }}
variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using{{ block.super }}
will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.Variables created outside of a
{% block %}
using the template tagas
syntax can't be used inside the block. For example, this template doesn't render anything:{% trans "Title" as title %} {% block content %}{{ title }}{% endblock %}
For extra readability, you can optionally give a name to your
{% endblock %}
tag. For example:{% block content %} ... {% endblock content %}
In larger templates, this technique helps you see which
{% block %}
tags are being closed.
Finally, note that you can't define multiple block
tags with the same
name in the same template. This limitation exists because a block tag works in
"both" directions. That is, a block tag doesn't just provide a hole to fill --
it also defines the content that fills the hole in the parent. If there were
two similarly-named block
tags in a template, that template's parent
wouldn't know which one of the blocks' content to use.
HTML の自動エスケープ¶
テンプレートから HTML を生成する時には、変数内の文字が HTML のレンダリング結果に悪影響を与えるというリスクが常に付きまといます。例えば、テンプレートに以下のような箇所がある場合を考えてみましょう:
Hello, {{ name }}
一見、このコードはユーザの名前を表示するだけの無害なものと思えます。しかし次のような値が名前として入力されていれば、何が起きるでしょうか:
<script>alert('hello')</script>
この値によって、テンプレートは次のように出力されます:
Hello, <script>alert('hello')</script>
……結果として、ブラウザに JavaScript の警告ボックスをポップアップさせることができてしまいます!
同様に、名前に '<'
文字が含まれていたらどうでしょうか:
<b>username
この値によって、テンプレートはこのように出力されます:
Hello, <b>username
これで、以降の Web ページの内容はすべて太字の表示になってしまいます!
ユーザーが入力したデータを無条件に信頼したり、直接 Web ページに挿入したりするべきでないことは明らかです。悪意のあるユーザは、この手の抜け穴を使って悪さをするものだからです。こうしたタイプのセキュリティホールの悪用は、 `クロスサイトスクリプティング `_(XSS) 攻撃と呼ばれています。
この問題を防ぐために、二つの方法があります:
- 一つは、信頼できない変数は必ず
escape
フィルタ (後で述べます) に通すことです。このフィルタは危害を及ぼす可能性をもつ HTML 文字を無害な文字に変換します。 この方法は初期の数年間において Django のデフォルトとして採用されていました。しかしユーザー、すなわち開発者やテンプレートの作者にとっては、すべてのデータをエスケープすることを忘れぬよう注意しなければならないという負担になるのが問題です。 - もう一つは、 Django の自動 HTML エスケープを使うというものです。この節の後半では自動エスケープの仕組みについて述べます。
デフォルトでは、Django はすべてのテンプレートの変数タグの出力を自動的にエスケープするよう設定されています。具体的には、以下の 5 つの文字がエスケープされます:
<
を<
に変換>
を>
に変換'
( シングルクォート ) を'
に変換"
( ダブルクォート ) を"
に変換&
を&
に変換
この動作は、デフォルトで適用されていることを重ねて強調しておきます。Django テンプレートシステムを使っているかぎり、あなたはエスケープに関する問題からは守られているのです。
自動エスケープをオフにする¶
サイト単位やテンプレート単位、あるいは変数単位でデータの自動エスケープ機能を無効にしたい場合には、いくつかの方法があります。
どんなときに、自動エスケープをオフにする必要があるでしょうか。テンプレート変数の中身は、生の HTML として出力するように意図されたデータかもしれません。そうした場合にはコンテンツがエスケープされてほしくはないでしょう。例えば、データベースに HTML を保存していてテンプレートに直接埋め込みたい場合を考えてみましょう。また、 Django のテンプレートシステムを使って、 HTML 以外 のデータ、例えば電子メールメッセージなどを生成したい場合もあるでしょう。
変数単位での制御¶
変数単位で個々に自動エスケープを無効にするには、 safe
フィルタを使います:
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
safe という言葉は、これ以上エスケープしないよう保護(safe)するとか、 HTML として解釈しても安全(safe)であるという意味だと考えてください。 例えば、 data
に '<b>'
が入っていた場合、出力は以下のようになります:
This will be escaped: <b>
This will not be escaped: <b>
テンプレートブロック単位での制御¶
テンプレート単位で自動エスケープを制御するには、テンプレート (または テンプレートの一部) を、以下のように autoescape
タグで囲みます:
{% autoescape off %}
Hello {{ name }}
{% endautoescape %}
autoescape
タグは、 on
または off
を引数にとります。 テンプレートのある範囲を自動エスケープし、さらにその一部で自動エスケープをオフにしたい場合には、次のようにできます:
Auto-escaping is on by default. Hello {{ name }}
{% autoescape off %}
This will not be auto-escaped: {{ data }}.
Nor this: {{ other_data }}
{% autoescape on %}
Auto-escaping applies again: {{ name }}
{% endautoescape %}
{% endautoescape %}
自動エスケープのタグは、他のブロックタグと同様、タグを設定したテンプレートを継承している他のテンプレートや、 :ttag:include
で取り込んだテンプレートでも有効です。例えば:
{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}
{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}
ベースのテンプレートで自動エスケープが無効化されているので、子テンプレートでも自動エスケープは無効化されます。結果として、 greeting
変数の値が ``<b>Hello!</b>'' のとき、以下の HTML が出力されます:
<h1>This & that</h1>
<b>Hello!</b>
Notes¶
一般に、テンプレートの作者は自動エスケープをあまり意識する必要はありません。 データをエスケープすべきではない場合を考えたり、データを適切にマークし、テンプレート上でうまく表示されるように考慮するのは、Python 側の開発者 (ビューやカスタムフィルタの開発者)であるべきです。
もしあなたが作成しているテンプレートがどういった状況で使われるのか分からず、自動エスケープが有効かどうかはっきりしない場合には、エスケープの必要な変数全てに escape
フィルタを追加してください。自動エスケープがオンの場合、 escape
フィルタがデータ を二重にエスケープするような危険性はありません。 escape
フィルタは自動エスケープされた変数には影響しなません。
文字列リテラルと自動エスケープ¶
先に説明したように、フィルタの引数は文字列であってもかまいません:
{{ data|default:"This is a string literal." }}
文字列リテラルは、すべて自動エスケープ**されずに**テンプレート内に挿入され、 safe
フィルタを通して渡されたかのように振る舞います。なぜならば、テンプレートの作者はその文字列リテラルに何が書かれているかは把握していますし、テンプレートが書かれる時点でテキストが正しくエスケープされていることは確認できるからです。
したがって、以下のようにテンプレートを書いてください:
{{ data|default:"3 < 2" }}
以下のようにはしないでください:
{{ data|default:"3 < 2" }} {# Bad! Don't do this. #}
この事が、変数自身に由来するデータに対して何かを引き起こす恐れはありません。 変数の内容はテンプレート作者の管理外にあり、必要に応じて自動的にエスケープされます。
メソッドへのアクセス¶
オブジェクトに備わったほとんどのメソッドは、テンプレートの中からでも呼び出すことができます。これはテンプレートからアクセスできる対象は、単にクラスの属性 (フィールド名のように) やビューを通した変数だけにはとどまらないということを意味します。例えば Django ORM は Foreign キーに関係するオブジェクトの集合を見つけるために "entry_set” という構文を提供しています。これによって、例えば “comment” と呼ばれるモデルが Foreign キーで ”task” というモデルに関連づけられている場合、テンプレートは task モデルに添えられた全ての comment に対して以下のようにアクセスできます:
{% for comment in task.comment_set.all %}
{{ comment }}
{% endfor %}
同じように、 QuerySets は、そこに含まれているオブジェクトの個数を数えるため count()
というメソッドを提供しています。これによって、 task と関連づけられた全てのコメントの数を取得することも出来ます:
{{ task.comment_set.all.count }}
そしてもちろん、モデル自身で明示的に定義したメソッドにも簡単にアクセスすることができます:
class Task(models.Model):
def foo(self):
return "bar"
{{ task.foo }}
Django ではテンプレート内でのプログラム的な処理を意図的に制限しているため、テンプレートからメソッドに引数を渡すことはできません。データはビューの中で計算され、テンプレートへは表示のためだけに渡されるべきだからです。
カスタムタグとカスタムフィルタのライブラリ¶
アプリケーションによっては、カスタムのタグやフィルタライブラリを提供しています。これらをテンプレートで使いたい場合、そのアプリケーションが INSTALLED_APPS
に追加されていることを確認し (以下の例では 'django.contrib.humanize'
が追加されているものとします) 、そしてテンプレート側で load
タグを使います:
{% load humanize %}
{{ 45000|intcomma }}
この例では、 load
タグは humanize
という名前のタグライブラリを読み込み、 intcomma
フィルタを使えるようにしています。 django.contrib.admindocs
が有効にされている場合、あなたの admin は現在インストールされているアプリケーションのドキュメント文字列を参照してカスタムライブラリの一覧を得ることができます。
load
タグは複数のライブラリ名を同時に読み込めます。ライブラリ名は スペースで区切って下さい:
{% load humanize i18n %}
カスタムのテンプレートライブラリを作成する方法については、:doc:'/howto/custom-template-tags` を参照してください。
カスタムライブラリとテンプレートの継承¶
カスタムタグやフィルタライブラリをロードした場合、タグやフィルタは現在のテンプレートだけで利用でき、テンプレート継承パスにおける親テンプレートや子テンプレートでは利用できません。
例えば foo.html
に {% load humanize %}
というタグが入っていても、子テンプレート ( {% extends "foo.html" %}
を使っているテンプレート) で humanize という名前のテンプレートタグやフィルタを使えるわけではありません。子テンプレート側で対応するには独自に {% load humanize %}
を入れる必要があります。
これはメンテナンス性と健全性を高めるための仕様です。
参考
- The Templates Reference
- ビルトインタグ、組み込みフィルタ、代替テンプレート、言語など多くをカバーしています。