Djangoのテンプレート

Google App EngineDjangoのテンプレートだけ使っていたのをみて, 自分でもやりたくなって調べてみた. ダウンロードしたパッケージを普通に

from django.template import Template, Context

とやって, 使おうとするとエラーがでて動かない.

 File "django/conf/__init__.py", line 53, in _import_settings
    raise EnvironmentError, "Environment variable %s is undefined." % ENVIRONMENT_VARIABLE
EnvironmentError: Environment variable DJANGO_SETTINGS_MODULE is undefined.

設定用のファイルを作って, それを環境変数をセットしないといけないらしい. 手軽にローカルに使うことだけを考えるとどうにも面倒くさい. ソースを追ってみたところ, django.conf.settingsの変数に値を設定すれば, 環境変数は書かなくてすむことが分かった.

import django.conf
django.conf.settings._target = django.conf.Settings("djangoSettings")
from django.template import Template, Context

アンダースコア付きの変数に代入していいのか, という気もするが, まあよかろう. でも, 設定ファイルはどうしても書かなければならないようだ. 面倒くさいなあ. 中身はなくてもかまわないのだが, とにかくファイルがないと怒られる. この場合はdjangoSettings.pyというファイルを空で作っておいておけばOK.

使い方はこんな感じ.

template="""{% for item in items %}
   <li> {{ item }} </li>
{% endfor %}"""
items = range(1,10)
print Template(template).render(Context(locals()))

とやると,

<li> 1 </li>
<li> 2 </li>
...

となる. これは便利.

リストの中身をカンマで区切って出力したいけど, 最後にカンマはつけたくない, というのはよくあるケース. そんな場合は特殊変数forloopを使う.

template="""{% for item in items %}
  {{ item }}{% if not forloop.last %}, {% endif %}
{% endfor %}"""

items = ['a', 'b', 'c']

print Template(template).render(Context(locals()))

これで,

a, b, c

が得られる. forloopのlastというプロパティは, ループの最後の周回の時のみTrueになるので, そのときだけはカンマの出力が抑制される, ということ. ほかにもfirst とかindexとかいろいろ定義されていて, 意外にいろんなことができそう.

# 実際にはこのテンプレートだと改行が入ってしまうが, HTMLの中なら問題は無い.

テンプレートはすごく便利でいいんだけど, テンプレート言語のセマンティクスが, どうしてもベース言語のそれとは異なるものになってしまうところが, つらいところ. いっそのこと, 統一規格を作ってくれないものだろうか. 一度書いたテンプレートを, PythonでもJavaScriptでも使えたりするとうれしいんだが.