フィルタを使って、値を変換する
ifを使って、Noneの値を出し分けたりしましたが、Noneのときにはデフォルト値(ゼロとか未選択を出したい!)を表示したい時には何となく冗長です。
そんなときには、フィルタを使うとスマートな表記ができます。
前回の views.pyはそのまま利用して、htmlテンプレートを編集します。
<html> <head> </head> <body> <p>サンプルアプリケーション はじめの一歩</p> <p>{{ none_data|default:"Noneは置き換えられます" }}</p> <p>{{ empty_data|default:"空文字列も置き換えます" }}</p> <p>{{ none_data|default_if_none:"Noneは置き換えられます" }}</p> <p>{{ empty_data|default_if_none:"空文字列は置き換えられません。" }}</p> <p>{{ abc|urlencode }}</p> </body> </html>
修正した後にブラウザでアクセスすると次のようになります。
<html> <head> </head> <body> <p>サンプルアプリケーション はじめの一歩</p> <p>Noneは置き換えられます</p> <p>空文字列も置き換えます</p> <p>Noneは置き換えられます</p> <p></p> <p>abc%E3%81%A7%E3%81%99%E3%81%A8%EF%BC%81</p> </body> </html>
defaultとdefault_if_noneでは挙動が異なり、defaultは Noneも空文字列も変換対象になりますが、default_if_noneでは、Noneだけが変換対象となります。
また、URLエンコードもフィルターで簡単に実現できます。しかし、エンコードする文字列の文字コードはシステムデフォルトの文字コードが使われるので注意が必要で、デフォルト以外の文字コードでエンコードしたい場合は、Viewで実装するか、新たに自分でフィルターの実装が必要です。
ということで、次回はフィルターを実装してみます。
Templateでのシンタックス
ViewからTemplateに値を渡して表示する方法がわかったら、次はその渡された値からHTMLを切り替えたり、列挙された値の取り出しをしてみます。
まずは views.py を編集します。今回は色々な値を設定します。
# vim:fileencoding=utf-8 from django.shortcuts import render_to_response def first(request): from datetime import datetime return render_to_response('first.html', { 'abc': u'abcですと!', 'none_data': None, 'empty_string': '', 'two_value': 2, })
マルチバイト文字列が入っているので、ファイル保存時にUTF-8にすること。
それと、先頭にファイルの文字コードを示すコメントが入っている点に注意してください。
続いて、first.htmlを書き換えます。
<html> <head> </head> <body> <p>サンプルアプリケーション はじめの一歩</p> {% if none_data %} <p>None値はこっちには入らない。</p> {% else %} <p>none_dataは Noneです</p> {% endif %} {% if emtpy_data %} <p>empty_data は空文字列なのでこっちに入ります。</p> {% else %} <p>empty_data はこっちに入ります。</p> {% endif %} <p> {% for ch in abc %} <span>{{ ch }}</span> {% endfor %} </p> {% ifequal two_value 2 %} <p>two_value は 2 なので表示される。</p> {% endifequal %} {% ifnotequal two_value 1 %} <p>two_value は 1 ではないので表示される。</p> {% endifnotequal %} </body> </html>
ブラウザでアクセスするとHTMLは以下のようになります。
(余分な改行を一部けずっています。)
<html> <head> </head> <body> <p>サンプルアプリケーション はじめの一歩</p> <p>none_dataは Noneです</p> <p>empty_data はこっちに入ります。</p> <p> <span>a</span> <span>b</span> <span>c</span> <span>で</span> <span>す</span> <span>と</span> <span>!</span> </p> <p>two_value は 2 なので表示される。</p> <p>two_value は 1 ではないので表示される。</p> </body> </html>
DjangoのTemplateでは、シンタックスというか制御文が入るところには、{% %}というタグを使用します。forで値を取り出すときも、Pythonのfor文に近い形で実装がされているため、"abcですと!"という部分は簡単に1文字ずつ処理できます。
その反面、凄く不便に感じるのが if の制御で比較演算子が一切使用できないことです。== はもちろん > とか < など全く使用できません。その代わりにサンプルコードでも使用している ifequal ifnotequal がありますが、細かい制御は Templateファイルがひたすら複雑になったりします。
Djangoでは、極力 Viewで表示用の処理を済ませてしまったり、Model側に表示用の関数を持たせることで、Templateに複雑なロジックを入れないのが良いと思います。ちなみに Templateでも引数無しの関数であれば、呼び出すことは可能です。
Templateで使用できる if や for は、組み込みタグとして分類されています。詳しくは Djangoのリファレンスを参照してください。(日本語訳は、1.0のマニュアルなので少し古いですが。。。)
次は、フィルターを使って表示する値をごにょごにょしてみたいと思います。