AppEngine/Python では長らく Kay Framework を使っていたんですが、最近は Flask に浮気気味です。Flask は URL マッピングをビューのデコレーターで記述できるのがステキですよね。Kay だと作成したビューに割り当てる URL パターンを urls.py に書き忘れて、デバッグ時にうがーってなることがたまにあったんですが、Flask ではまず無いです。
そんな Flask の長所でもあり欠点でもあるのは、ビューとテンプレートだけなこと。モデルは自前で用意しなければいけません。しかし、もともと AppEngine/Python には db モジュールがあるから無問題。
…と思ってたら、フォームもありませんでした。忘れてた。AppEngine に標準で付いている django のフォームを使ってもいいんですが、WTForms を採用。
Flask Extensions には、WTForms をあたかも Flask に組み込まれているかのように使える拡張があります。
今回は素の WTForms を使いますけど。
フォームといったらもっぱら Kay のものばかり使っていたので、WTForms は使い勝手が違っていて戸惑いました。
# -*- coding: utf-8 -*- from google.appengine.ext import db from flask import ( Flask, request, redirect, url_for, render_template, ) from wtforms import ( Form, TextField, TextAreaField, ) from wtforms.validators import ( Required, Length, ) ... # モデル class Entry(db.Model): title = db.StringProperty(required=True) content = db.TextProperty(required=True) created = db.DateTimeProperty(auto_now_add=True) # フォーム class EntryForm(Form): title = TextField(u"タイトル", validators=[ Required(u"タイトルを入力してください"), Length(min=1, max=32, message=u"タイトルは32文字以内にしてください") ]) content = TextAreaField(u"本文", validators=[ Required(u"本文を入力してください") ]) # フォームを使って入力検証 @app.rotue("/entry/create", methods=["POST"]) def index(): form = EntryForm(request.form) if form.validate(): entry = Entry(title=form.title.data, content=form.content.data) entry.put() return redirect(url_for("index")) return render_template("entry_edit.html", form=form) ...
各 Field の validators パラメータで検証内容を指定するところがいいですね。Field と分離されているので、独自の検証内容を追加でき、さらには使い回せます。ソースを見たところ、検証で使うクラスを自作するのは難しくなさそうです。
んで、フォームを HTML で表示。
<html> <body> ... <!-- フォームを描画 --> <form method="POST" action="/entry/create"> タイトル:<br/> {{ form.title() }}<br/> 本文:<br/> {{ form.content() }}<br/> <input type="submit" value="公開"/> </form> ... </body> </html>
Kay のフォームに慣れているせいか、form タグを使って HTML である程度フォームを記述しなければいけないのが、最初面倒に感じました。でも、フォームのラベルとかエラー表示とかをカスタマイズしようと思ったとき、Kay だと複雑な記述が必要だったので、これくらいシンプルな方がいいのかも。