[Python][TurboGears] TurboGearsでBlog作ってみる その4 フォームウィジェット

TurboGearsでは再利用可能なビューをウィジェットとして取り扱うことができる。

widgets.TableForm などを使ってその3で作ったビューをウィジェットにしてみよう。

ウィジェットを使うには、turbogears.wigets モジュールが必要

from turbogears import wigets

ウィジェットの定義。
kidテンプレートの中でごちゃごちゃやるより、遥かに楽だ。

class BlogEditFields (widgets.WidgetsList):
    id = widgets.HiddenField('id')
    date = widgets.CalendarDatePicker("date", 
                                      label=unicode('日付', 'utf-8'),
                                      validator=validators.DateTimeConverter(format='%Y/%m/%d'),
                                      format='%Y/%m/%d')

    title = widgets.TextField("title",
                              label=unicode('タイトル', 'utf-8'),
                              validator=validators.UnicodeString(not_empty=True))
    description = widgets.TextArea("description",
                                   label=unicode('内容', 'utf-8'),
                                    validator=validators.UnicodeString(not_empty=True))

editBlogForm = widgets.TableForm(fields=BlogEditFields(),
                                 submit_text=unicode('保存', 'utf-8'))

TextFieldやHiddenFieldは名前のとおり。
CalendarDatePickerは入力フィールドと、選択可能なカレンダーを組み合わせたものだ。
使えるウィジェットはtoolboxのWidget Browserで確認できる。

$ tg_admin toolbox

TableForm の fields引数は、ウィジェットのリストでもよいので、WidgetsList は別に使わなくてもいいのだが、名前空間を切れるのと、リストの中でごちゃごちゃやらなくてすむので使っている。
editBlogForm がフォームィジェットになる。
kidテンプレート内で使うため、editBlog メソッドの戻り値に追加する。

        return dict(inputs=inputs, tg_errors=tg_errors,
                    editForm=editBlogForm)

kidテンプレートの中で、editBlogForm を呼び出す(__call__)とフォームウィジェットXHTMLを出力してくれる。
引数で値を指定すると、その値を各フィールドに設定してくれる。
入力エラー時には、自動で値保持をしていてくれるが、更新の場合を考慮してコントローラから入力値を渡すようにしている。

  <form py:replace="editForm(action='saveBlog', method='POST', value=inputs)"/>

フォームウィジェットはバリデータも持っている。
validate デコレータに渡すと、入力チェックをしてくれる。
saveBlogメソッドの入力チェックをeditBlogFormで行う場合は以下のようになる。

    @expose()
    @error_handler(editBlog)
    @validate(editBlogForm)
    @identity.require(identity.not_anonymous())
    def saveBlog(self, id=None, date=None, title=None, description=None):

いいね。DRYだね。