Django テンプレートの基本(変数・フィルタ・タグ)

Django テンプレートは、HTML の中に Python の変数やロジックを埋め込む仕組みです。ビューから渡されたデータを {{ }} で表示し、{% %} で制御構文を書くというシンプルなルールで成り立っています。

変数の表示

ビューからテンプレートに渡された変数は、二重波括弧 {{ }} で表示します。

# views.py
def article_detail(request, pk):
    article = Article.objects.get(pk=pk)
    return render(request, 'articles/detail.html', {
        'article': article
    })
<!-- detail.html -->
<h1>{{ article.title }}</h1>
<p>{{ article.body }}</p>
<span>{{ article.published_at }}</span>

ドット記法でオブジェクトの属性、辞書のキー、リストのインデックスにアクセスできます。

{{ user.username }}
{{ config.debug }}
{{ items.0 }}

変数が存在しない場合や None の場合は、デフォルトでは空文字が表示されます。エラーにはなりません。

フィルタで表示を加工する

フィルタはパイプ | を使って変数の出力を加工します。Python でいうところのメソッドチェーンに近い感覚です。

<!-- 文字数を30文字に切り詰める -->
<p>{{ article.body|truncatechars:30 }}</p>

<!-- 日付をフォーマット -->
<span>{{ article.published_at|date:"Y年n月j日" }}</span>

<!-- デフォルト値を設定 -->
<p>{{ article.category|default:"未分類" }}</p>

よく使うフィルタを確認しておきましょう。

フィルタ用途
length要素数・文字数{{ items|length }}
lower / upper大文字小文字変換{{ name|lower }}
truncatechars指定文字数で切り詰め{{ text|truncatechars:50 }}
フィルタ用途
date日時フォーマット{{ dt|date:"Y-m-d" }}
defaultNone 時のデフォルト値{{ val|default:"なし" }}
linebreaksbr改行を br タグに変換{{ text|linebreaksbr }}

フィルタは連結できます。{{ name|lower|truncatechars:10 }} のように、左から順に適用されます。

タグで制御構文を書く

テンプレートタグは {% %} で囲み、条件分岐やループなどの制御構文を実現します。

{% if articles %}
  <ul>
    {% for article in articles %}
      <li>{{ article.title }}</li>
    {% endfor %}
  </ul>
{% else %}
  <p>記事がありません。</p>
{% endif %}

{% if %}{% for %} には必ず対応する終了タグ({% endif %}{% endfor %})が必要です。Python と違ってインデントでブロックを判定しないため、閉じ忘れに注意してください。

for ループの便利な変数

{% for %} の中では forloop という特殊変数が使えます。

{% for article in articles %}
  <div>
    {{ forloop.counter }}. {{ article.title }}
    {% if forloop.first %}(最新){% endif %}
  </div>
{% endfor %}
変数内容
forloop.counter1 から始まる番号
forloop.counter00 から始まる番号
forloop.first最初のループなら True

forloop.last を使えば最後の要素だけ区切り文字を省くといった処理も簡潔に書けます。

コメント

テンプレート内のコメントは {# #} で書きます。HTML コメント <!-- --> と違い、ブラウザには出力されません。

{# この部分はレンダリングされない #}
<p>{{ article.title }}</p>

複数行のコメントには {% comment %} タグを使います。

{% comment %}
  この範囲はすべて無視される。
  デバッグ中に一時的にブロックを無効化するときに便利。
{% endcomment %}

自動エスケープ

Django テンプレートは変数を表示する際、HTML の特殊文字(<>&" など)を自動的にエスケープします。これにより、ユーザー入力をそのまま表示しても XSS(クロスサイトスクリプティング)攻撃を防げます。

<!-- ユーザー入力が <script>alert('xss')</script> でも安全 -->
<p>{{ user_input }}</p>
<!-- 出力: &lt;script&gt;alert('xss')&lt;/script&gt; -->

意図的に HTML をそのまま出力したい場合は |safe フィルタを使いますが、信頼できるデータにのみ適用してください。

{{ trusted_html|safe }}

Django テンプレートの基本は「{{ }} で表示、{% %} で制御、| で加工」の 3 つです。この 3 つを押さえておけば、ほとんどのテンプレートを読み書きできるようになります。