Django Template Language
(DTL
)でのエスケープメモ
htmlレンダリングで使うDTL
のデフォルトでは、変数を展開すると、自動で文字実体参照などの実体参照に置き換えられてしまう。(エスケープされてしまう。)
html要素(htmlタグ)を変数を使って埋め込みたいなど、変数をそのままレンダリングしたい(非エスケープしたい)ときもある。その方法を2つ挙げる。
環境
- Django==3.0.8
safeフィルターを利用
Djangoにビルトインされたsafe
フィルタを使えば、変数展開時にエスケープさせずにおける。参考:Built-in template tags and filters | Django documentation | Django
変数をいつも通り{{ }}
で囲み、safe
フィルタを通すだけ。
{{ h1_hello }}
{{ h1_hello|safe }}
そして変数に次の値を格納する:
context = {'h1_hello': '<h1>こんにちは</h1>'}
この出力は次のようになる:
<h1>こんにちは</h1>
<h1>こんにちは</h1>
このようにsafe
フィルタを通せば、エスケープされずに出力される。
変数を展開するごとに|safe
をつける必要がある。
autoescapeタグを利用
Djangoにビルトインされたautoescape
タグを使えば、囲ったブロックをまとめてエスケープせずにおける。参考:Built-in template tags and filters | Django documentation | Django
エスケープしたくないところを{% autoescape off %}
と{% endautoescape %}
で挟めばいい。
off
をon
にすればエスケープされる。DTL
では自動エスケープがデフォルトでオンになっている。
{% autoescape on %}
{{ h1_hello }}
{{ two_elements_text }}
{% endautoescape %}
{% autoescape off %}
{{ h1_hello }}
{{ two_elements_text }}
{% endautoescape %}
変数の値を次にようにする:
context = {
'h1_hello': '<h1>こんにちは</h1>',
'two_elements_text': """
<h1>今日も</h1>
<p>いい天気。</p>
"""
}
すると出力は次のようになる:
<h1>こんにちは</h1>
<h1>今日も</h1>
<p>いい天気。</p>
<h1>こんにちは</h1>
<h1>今日も</h1>
<p>いい天気。</p>
本当は、two_elements_text
はstr.strip()
しないと、改行やインデントが酷くなる。サンプルでは修正した。
このタグは入れ子にして内側で再度on
にもできる。また、{% autoescape off %}
タグの中ならinclude
したテンプレート内でも、自動エスケープしなくなる点には注意する。
使い分ける
safe
フィルタは局所的にエスケープの回避ができる。autoescape
タグはブロック単位で制御できる。
safe
フィルタばかり書いて大変だなと思ったらautoescape
タグの利用を考えるくらいでいいだろう。
autoescape
タグは中身の子テンプレートにも影響が行くので、おかしいと思ったら確認すること。
以上です。
広告