Django: テンプレート変数内のHTMLタグがエスケープされる問題を解決する方法

2010年2月14日

関連記事
Djangoでは、テンプレートファイル内に{{veriable}}と記述すると変数として扱われます。 これをハンドラ側(コントロール側)で定義することによって、様々な変数をマッピングできます。 最も簡単な例を以下に示しましょう。
1
2
3
4
5
<html>
    <body>
        {{hel}}
    </body>
</html>

上記は最も簡単なテンプレートファイルの例です。

ここでハンドラ側で、テンプレート変数: helに

hel = '<font color="red"> hogehoge </font>'
のようにHTML文字列を代入したとしましょう。
これはhogehogeという文字を赤色で表示するためのHTML文ですね。 

しかし、実際にはhogehogeは赤色で表示されることはありません。 

それどころかHTMLタグもそのまま表示されてしまいます。

これは、Djangoの設計思想で、プログラマにエスケープしなければいけない文字を意識させないための処置です。つまり、デフォルトではあらゆるテンプレート文字内の 禁止文字はエスケープされるようになっているのです。
エスケープ対象文字は以下の4つです。


 ・「<」 は &lt; に変換されます。 

 ・「>」 は &gt; に変換されます。

 ・「'」 (クオート) は &#39; に変換されます。 

 ・「"」 (二重クオート) は &quot; に変換されます。 

 ・「&」 は &amp; に変換されます。


上記エスケープ対象文字を自動エスケープさせずそのまま表示することができれば、 HTMLタグもそのままブラウザに解釈され、上記例のhogehogeも赤色で表示されるようになります。
Djangoではそのような方法を提供していて、「| safe」というフィルター関数を テンプレート文字列に添えるだけで済むのです。
具体的には上記HTMLを以下のように変更します。

<html> <body> {{hel | safe}} </body> </html>

これで、helにHTML文字列を挿入してもそのまま表示されるようになります。 また、「| safe」の代わりにブロック指定する方法もあります。

1
2
3
4
5
6
7
<html>
    <body>
        {% autoescape off %}
             {{hel}}
        {% endautoescape %}
    </body>
</html>

上記のようにすると、「autoescape」で囲まれた部分の全てのtemplate文字に「| safe」が 適用されるのと同じ状態になります。

Django本家の資料も参考に、使いこなしてみてください。