Flask と SQLAlchemy と WTForms

[twitter:@nobonobo] さんのつぶやきをみて SQLAlchemy でも出来るんのかもとソースみたら出来そうだったのでやってみた。
# ドキュメントには特に書いてなかった


db.py

# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///test.db', convert_unicode=True)
db_session = scoped_session(
    sessionmaker(autocommit=False, autoflush=False, bind=engine)
)
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    from models import User
    Base.metadata.create_all(bind=engine)

models.py

# -*- coding: utf-8 -*-
from sqlalchemy import Column, Integer, String
from db import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)
    
    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r, %r>' % (self.name, self.email)

app.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, render_template
from wtforms.ext.sqlalchemy.orm import model_form
from db import db_session
from models import User

app = Flask(__name__)
    
@app.teardown_request
def shutdown_session(exception=None):
    db_session.remove()
    
@app.route('/')
def index():
        
    UserForm = model_form(User)
    form = UserForm()

    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

templates/index.html

<!DOCTYPE HTML>
<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>Sample</title>
  </head>
  <body>
    <div>{{ form.name.label }}{{ form.name }}</div>
    <div>{{ form.email.label }}{{ form.email }}</div>
  </body>
</html>

結果

<!DOCTYPE HTML>
<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>Sample</title>
  </head>
  <body>
    <div><label for="name">Name</label><input id="name" name="name" type="text" value="" /></div>
    <div><label for="email">Email</label><input id="email" name="email" type="text" value="" /></div>
  </body>
</html>

ということで WTForms と SQLAlchemy のモデルを連携するのは出来た。
ただ、国際化や複雑なバリデーションを model_form にインジェクションする方法が良くわからない。
model_form の引数に field_args を上手く使えばいいのかなー。