[TurboGears] ウィジェットに渡したvalue変数は、テンプレート内では辞書になる。
環境
この記事の内容は、TurboGears 1.0.1で確認しました。
現象
turbogears.widgets.forms.CompoundInputWidgetクラスを継承しているクラス(Formクラスなど)のdisplayメソッドのvalue引数に属性を持つオブジェクトを渡すとします。例えば、
class Foo: pass foo = Foo() foo.bar = "baz"
のように生成したオブジェクトと、
class Hoge(Form): template = """ (略) """ hoge = Hoge()
というフォームウィジェットがあり、これらをテンプレート内で、
${hoge.display(value=foo)}
として使用します。すると、Hogeクラスのテンプレート内では、変数valueは辞書となっており、barという属性を読み出すためには、
${value['bar']}
としなければなりません。
詳細
turbogears.widgets.base.Widgetクラスでは、displayメソッドは以下のようになっています。
class Widget(object): (略) def display(self, value=None, **params): (略) params["value"] = to_unicode(self.adjust_value(value, **params)) (略)
この中のadjust_valueメソッドは、turbogears.widgets.forms.CompoundInputWidgetで以下のようにdictify_valueメソッドを呼び出しています。このdictify_valueメソッドを使って、変数valueの型を辞書に変換しています。
class CompoundInputWidget(CompoundWidget, InputWidget): (略) def dictify_value(self, value): """Converts a value into a dict suitable for propagating values to child widgets. If value is a dict it will pass thorugh, if it other kind of object, attributes which match child widgets' names will be tried to fetch.""" if isinstance(value, dict): return value else: value_as_dict = {} for w in self.iter_member_widgets(): try: value_as_dict[w.name] = getattr(value, w.name) except AttributeError: pass return value_as_dict def adjust_value(self, value=None, **params): """Adjust a value for displaying in a widget.""" if value is not None: value = self.dictify_value(value) return super(CompoundWidget, self).adjust_value(value, **params)