Hatena::Grouppython

nelnal@python

2009-08-25

[] 「Django Book」をやってみる:Chapter 4 Templates その2 23:11  「Django Book」をやってみる:Chapter 4 Templates その2 - nelnal@python を含むブックマーク はてなブックマーク -  「Django Book」をやってみる:Chapter 4 Templates その2 - nelnal@python

複雑なデータを使用する。

ここでは今までの様な単純なデータを使用してましたが、より複雑なデータをContextクラスに取り込んだ場合でも簡単な記述で使用出来る様に変換する仕組みを備えています。


例えば辞書型の場合

>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
u'Sally is 43 years old.'

また、オブジェクトの属性(Attribute)も上手く取り扱うことが出来ます。

>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The manth is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
u'The manth is 5 and the year is 1993.'

当然自分で作成したクラスにも対応出来ます。

>>> from django.template import Template, Context
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...             self.first_name, self.last_name = first_name, last_name
... 
>>> t = Template('Hello, {{ person.first_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
u'Hello, John.'

さらにオブジェクトのメソッドについても使用可能です。

丸括弧を付ける必要はありません。

>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
u'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
u'123 -- 123 -- True'

最後に配列の要素へのアクセス方法についても記載します。

>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
u'Item 2 is carrots.'


メソッド呼び出し時の振る舞い(例外の処理について)

メソッドの呼び出しについては他の属性の呼び出しと似ている部分が多いですが、

メソッドの処理に失敗した場合の振る舞いが違ってきます。


メッソドの実行中に例外が発生した場合は通常のPythonプログラムと同様に処理を中断して例外の発生をメッセージとして表示します。

しかし、raiseする例外クラスの属性「silent_variable_failure = True」を追加した場合は、例外の発生を無視して空のデータを返して実行を継続することが出来る。

>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
...     def first_name(self):
...             raise AssertionError, "foo"
...
>>> p = PersonClass3()
>>> t.render(Context({"person": p}))
Traceback (most recent call last):
   ...
AssertionError: foo
>>> # 例外の発生を無視する
>>> class SilentAssertionError(AssertionError):
...     silent_variable_failure = True
...
>>> class PersonClass4:
...     def first_name(self):
...             raise SilentAssertionError
... 
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
u'My name is .'

また、ここであるオブジェクト(ここでは BankAccount とする)が delete メソッドを持っているとします。

もしテンプレートが {{ account.delete }} を含んでいた場合*1にテンプレートを展開しようとするとオブジェクトが削除されてしまうことになってしまいます。

もしこれを防ごうとする場合、delete メソッドに alters_data という属性を付与し、値を True にすることによって対処します。

def delete(self):
    # Delete the account
    ...
delete.alters_data = True

これによってテンプレートを展開する際にメソッドを実行出来なくなります。

上記の例で言うと {{ account.delete }} を展開する際に delete メソッドは実行されず、また警告も出ずに失敗することになります。



Next --> Chapter 4 その3

*1:account は BankAccount のインスタンス

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20090825