The Django Form Validation Framework on Google App Engine
Django Form Validation Framework を Google App Engine で使ってみる。
インポート
この前のTODO アプリケーション でやってみる。
djangoforms をインポートするが
from google.appengine.ext.webapp import template
の後ろで
from google.appengine.ext.db import djangoforms
とインポートする。
フォームクラスの定義
djangoforms.ModelForm を派生したクラス。Meta サブクラスでモデルとフォームに表示しないプロパティを指定する。exclude のかわりに fields と使うと表示するプロパティの指定もできる。
auto_now, auto_now_add が指定してあるものは自動的にフォームには表示されないらしい。
フォーム表示時には default によって初期値が設定される。choices はドロップダウンになる。
#### フォームクラス class TodoForm(djangoforms.ModelForm): class Meta: model = Todo # モデル指定 exclude = ['owner'] # フォームに不要なプロパティリスト
モデルに verbose_name を指定しておくとそれをフォームの項目名に表示してくれる。
#### モデル class Todo(db.Model): owner = db.UserProperty() content = db.StringProperty(verbose_name='内容', required=True) deadline = db.DateProperty(verbose_name='締切容', required=True) done = db.BooleanProperty(verbose_name='済')
フォームを使う
TodoForm() とすれば、フォーム部分が生成されるらしい。生成されるフォームは tr タグからなので table タグで囲む必要がある。
ポストされたものは data = TodoForm(data = self.request.POST) で取得でき、data.is_valid() で検証が走る。
data.save でモデルが返ってくる。commit=False を指定しない場合はこの時点でデータストアに保存される。ここでは owner を設定したいので commit=False とし、owner 設定後に put する。
検証失敗時は data をそのまま表示すればエラーメッセージ付きのフォームが生成される。
#### TODO 追加ページ class AddPage(webapp.RequestHandler): ### TODO 追加ページのテンプレートへ def get(self): path = os.path.join(os.path.dirname(__file__), 'add.html') self.response.out.write(template.render(path, {'form': TodoForm()})) ### TODO をデータストアに保存して / にリダイレクト def post(self): data = TodoForm(data = self.request.POST) if data.is_valid(): ## 入力エラーなし todo = data.save(commit=False) # owner をセットするので commit=False todo.owner = users.get_current_user() todo.put() # ここでデータストアに self.redirect('/') else: ## 入力エラーあり path = os.path.join(os.path.dirname(__file__), 'add.html') self.response.out.write(template.render(path, {'form': data}))
add.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>TODO 追加ページ</title> </head> <body> <h1>TODO を追加します</h1> <form action="/add" method="post"> <table> {{form}} </table> <input type="submit" value="追加する"> </form> <a href="/">キャンセル</a> </body> </html>
その他
- エラーメッセージのカスタマイズ(日本語化)はどうやるんだろう?
- 値が None のものがあると order できない?
- モデルの default はその値がキャッシュされているので users.get_current_user() 等は指定できない。__init__() で初期化する。