formencode

FormEncode — FormEncode 2.0.0a1 documentationの使い方

フォームバリデーションライブラリ。

ドキュメント見ても今一わかりづらいので、以下エグザンプル。

from formencode import htmlfill
from formencode import Schema
from formencode import validators as vs
from formencode.api import Invalid

from google.appengine.ext import db
class SomeModel(db.Model):
  ...

class UniqueCode(vs.String):
  messages = {'existed': "%(value)s is already existed"}
  def validate_python(self, value, state):
    if SomeModel.all().filter('code =', value).count(1) > 0:
      raise vs.Invalid(self.message('existed', state, value=value), value, state)

class SomeModelForm(Schema):
  filter_extra_fields = allow_extra_fields = True
  code = UniqueCode(not_empty=True)
  color = vs.Int(not_empty=True)
  stock = vs.Int(if_missing=0)

def new(request):
  form = SomeModelForm()
  errors = {}
  if request.method == 'POST':
    try:
      new = Fabric(**form.to_python(request.form))
      new.put()
      return redirect(reverse('index'))
    except Invalid, e:
      errors = e.error_dict
  response = render_to_string('new.html')
  return Response(htmlfill.render(response, request.form or {'selected': True}, errors))

htmlfillはHTMLを簡単にパースしてvalue=""を埋めてくれるというもの。フォームの出力を(複雑でなければ)静的なものにでき、フォームのあるページもキャッシュできる。HTML自体が馬鹿でかいものでなければ、それほど遅くもない。