• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Form libraries
 

Form libraries

on

  • 1,615 views

Pycon JP 2011 8/27

Pycon JP 2011 8/27

Statistics

Views

Total Views
1,615
Views on SlideShare
1,615
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Form libraries Form libraries Presentation Transcript

    • VariousWeb Form Widget Toolkits aodag Pycon JP 2011
    • お前誰よ@aodag小田切篤BeProud勤務今別の部屋で発表しているianと同僚Djangoきらいです(´・ω・`) PylonsとかPyramidとか、既存のコンポーネント組み合わせてるもののほうが好きです。
    • SQLAlchemy● データマッパー● すごく柔軟
    • WSGI (PEP-333, PEP-3333)PythonのWebアプリケーション標準def hello(environ, start_response): start_response("200 OK", [(Content-type, text/plain)]) return ["Hello, world!"]
    • AdminアプリケーションDjangoのadmin(だけ)はいいね!SQLAlchemyにも同じようなものがほしいWSGIアプリで全般的に使いたい(あまりフレームワークに依存したくない)Ajaxばりばりである必要はないけど、DatePickerとかSuggestとか、入力補助系のJSが利用できるとよい
    • Adminアプリケーション● クラスごとにサブアプリケーション● グリッド表示と検索● 入力フォーム● カスタムアクションを追加できる
    • フォームライブラリを調査Form Libraryの役割比較ライブラリ
    • Form Libraryの役割● HTMLフォーム生成● バリデーション
    • 比較ライブラリ● ToscaWidgets / Sprox● FormAlchemy● tw2.sqla● WTForms● deform/colander
    • 比較のポイント● SQLAlchemyとの親和性● バリデータのカスタマイズ● フィールドのカスタマイズ● ウィジェットのカスタマイズ
    • ToscaWidgets / Sprox● SproxはSQLAlchemyのスキーマからToscaWidgetsのフォームを 作成します● SQLAlchemyのスキーマ以外のフィールドをフォームに追加した り、スキーマのフィールドをフォームから削除したりできます。● formencodeでカスタムバリデータを作成します● tw.formsでカスタムフィールドを作成します
    • FormAlchemy● SQLAlchemyだけでなく、zope.schemaなどにも対応● SQLAlchemyのスキーマ対応は一番すぐれている● デフォルトで用意されているウィジェットレンダラーが少ない● 実行時にもフィールド定義を変更可能● jqueryuiを使ったfa.jqueryのような追加スキンが存在する
    • tw2● ToscaWidgetsの後継● まだ a4がリリースされたばかり、 発展途上● SQLAlchemyから自動生成するフォームがある ○ many-to-manyまでは対応できてない● SQLAlchemyというよりElixirに対応している
    • wtforms● SQLAlchemyからのスキーマ生成はしない● SelectのoptionをSQLAlchemyのクエリで設定可能● 機能は少なめ● その分はまりどころが少なく枯れるのが早そう● フォーム全体の生成はしない● グリッド生成もしない● ToscaWidgetsのtw.formsと名前が紛らわしい><
    • deform / colander ● colanderはスキーマ定義 ● deformはcolanderに対応しているフォームライブラリ ● SQLAlchemyからのスキーマ生成できない ● ウィジェットが豊富 ● ajaxとりこみに意欲的 ● deferred bindingにより実行時にウィジェットやバリデーションを変 更可能 ● テンプレートにchameleon(zope page template)を使っている ● テンプレートをmakoに入れ替えるプロジェクトが進行中http://deformdemo.repoze.org/
    • Sample ModelSQLAlchemy ● User ○ user_name ○ password ○ user_image ○ groups ● Group ○ name ○ users ○ permissions ● Permission ○ name ○ groups
    • ポイント● 全部many-to-manyの関連付け● User - Group - Permission● User - Permissionの派生関連付け● _password 直接見せたくないフィールド● ユーザー画像はファイル保存
    • Userフォーム Sproxclass UserForm(AddRecordForm): __model__ = models.User __require_fields__ = [user_name] __omit_fields__ = [_password] __field_order__ = [user_name, password, groups] password = tw.forms.PasswordField(password, validator=tw.forms.validators.NotEmpty)
    • Userグリッド Sproxclass UserTable(TableBase): __model__ = models.Useruser_table = UserTable(models.DBSession)class UserTableFiller(TableFiller): __model__ = models.Useruser_table_filler = UserTableFiller(models.DBSession)user_table(user_table_filler.get_value())
    • Sprox雑感● AddRecordFormとEditableFormをそれぞれ作らないといけない● SQLAlchemy0.7で動かない!● many-to-manyがうまくフォームに反映されない● デフォルトでアルファベット順になってしまうので、いい感じの順 番にするには、全部指定しなおさないといけません(´・ω・`) 
    • (´・ω・`) そろそろオワコン?
    • Userフォーム FormAlchemyclass UserForm(FieldSet): def __init__(self, **kw): super(UserForm, self).__init__(model=User, **kw) excludes = [self._password] # 追加フィールド self.insert_after(self.user_name, Field(password).password().required()) self.configure(exclude=excludes) # フォーム全体の設定
    • User グリッド FormAlchemyclass UserGrid(Grid): def __init__(self, **kw): super(UserGrid, self).__init__(cls=models.User, **kw) # Edit用のリンク追加 self.append(Field(edit_link, value=lambda u: <a href="%s/edit">Edit</a> % u.id)) self.configure(readonly=True, exclude=[self._password])users = models.DBSession.query(models.User).all()grid = user_grid.bind(users)
    • FormAlchemy雑感やっぱりSQLAlchemy0.7で動かない(´・ω・`) fa.jqueryはまだ安定していないmany-to-manyをしっかりおいかけてくれる開発が活発なので、今後に期待できる
    • 全体的には(・∀・)イイ! と思う
    • Userフォーム tw2.sqlaclass UserForm(tw2.sqla.DbFormPage): entity = models.User class child(tw2.forms.TableForm): user_name = tw2.forms.TextField(validator=tw2.core.Required) password = tw2.forms.PasswordField(validator=tw2.core.Required) user_image = tw2.forms.FileField() groups = tw2.sqla.DbSingleSelectField(entity=models.Group)
    • ● SQLAlchemyのスキーマから自動生成する機能が追加されてき ていますが、使い物になりませんでした。(´・ω・`) ● あと、entityクラスのqueryメソッドを呼ぼうとしたり、Elixirを前提に しすぎです。● 遅延評価できるselectウィジェットに複数選択可能なものがなく、 many-to-manyの関連付けに困ります
    • (゚д゚)マダマダ
    • Userフォーム WTFormsdef group_factory(): return models.DBSession.query(models.Group)class UserForm(wtforms.Form): username = wtforms.TextField(User Name) password = wtforms.PasswordField(Password) groups = QuerySelectMultipleField(query_factory=group_factory )
    • WTForms表示<form method="post"><table>${self.field_row(form.username)}${self.field_row(form.password)}${self.field_row(form.groups)}</table><button type="submit">Add</button></form>
    • WTForms 表示<%def name="field_row(field)"><tr><td>${field.label}</td><td>${field()}</td></tr></%def>
    • WTForms 雑感● やれることが少ない分、はまりどころはなさそうです● でもフォームライブラリ使ってるのにHTMLテーブル書くのはやで す。● B2Cサイトで複雑なHTMLに入れるのに向いてそうですが、そん なことは他のフォームライブラリでできます
    • 機能少なすぎね? (´・ω・`) 
    • Userフォーム deformclass UserSchema(c.MappingSchema): # colanderはSQLAlchemyから自動生成しない user_name = c.SchemaNode(c.String()) password = c.SchemaNode(c.String(), widget=w.PasswordWidget())form = Form(UserSchema(), buttons=(save,))
    • colanderのdeferred bind 定義実行時に、ウィジェット、やバリデータを切り替える仕組み@c.deferreddef group_select_widget(node, kw): groups = kw[groups] return w.SelectWidget(values=[ (g.id, g.group_name) for g in groups ])
    • colander deffered bindingclass Group(c.MappingSchema): # groupを選択するためのスキーマ group_id = c.SchemaNode(c.String(), widget=group_select_widget)class Groups(c.SequenceSchema): # groupを複数選択するためのスキーマ group = Group()class UserSchema(c.MappingSchema): ...... groups = Groups()
    • colanderのdeferred bind バインディングschema = UserSchema()groups = DBSession.query(Group)# バインドschema = schema.bind(groups=groups)form = Form(schema, ....)
    • User フォーム deform バリデーションtry: params = form.validate(controls)except ValidationFailure, e: e.render()
    • deform 雑感● フォームでやりたいことは、おそらくなんでもできます。● シーケンススキーマやマッピングスキーマを組み合わせることで、 複雑な階層を持つスキーマも作成可能。● その分ライブラリの構造が複雑です。
    • (´  > ω < ) むずかしー!
    • ひとまずSQLAlchemyのデータ管理ツールを作るなら、FormAlchemyが一番サポートされている。fa.jqueryは様子見たほうがいい。1リクエストで複数のモデルを扱う場合は、colander / deform がほぼどんな構造でも対応できる。MongoDBなどスキーマレスDBを使う場合は、こちらをおすすめする。
    • スタティックファイルの管理deformやfa.jqueryはjquery.jsやjqueryui.js、その他cssなどが必要フロントのApacheやnginexに任せてしまいたいが、フォームライブラリが使うスタティックファイルはどこにあるのか?ウィジェットライブラリが依存するjsなどをどう管理していくか?
    • Paste deployでがんばr[app:deform_static]use = egg:paste#pkg_resourcesegg = deformresource_name = deform/static[composite:deform]use = egg:paste#urlmap/ = deform_app/static = deform_static[pipeline:deform_demo]pipeline = egg:repoze.tm2#tm deform
    • Fanstatic ● スタティックファイルをホスティングするWSGIアプリ ● スタティックファイルを管理するユーティリティ、ミドルウェア ● fa.jqueryは今後これを使うようになる予定http://pypi.python.org/pypi?%3Aaction=search&term=fanstatic&submit=search
    • Fanstatic 例from fanstatic import Fanstaticfrom js.jqueryui import jqueryui@wsgifydef app(request): jqueryui.need() return Response(body)app = Fanstatic(app)
    • Fanstatic 例body = """<html><head></head><body>Hello</body></html>"""
    • Fanstatic 例 実行結果<html><head> <script type="text/javascript" src="/fanstatic/jquery/jquery.js"></script><script type="text/javascript" src="/fanstatic/jqueryui/ui/jquery-ui.js"></script></head><body>Hello</body></html>
    • 参考● SQLAlchemy http://www.sqlalchemy.org/● ToscaWidgets http://toscawidgets.org/● formencode http://formencode.org/● Sprox http://sprox.org/● tw2 http://toscawidgets.org/documentation/tw2.core/● formalchemy http://docs.formalchemy.org/formalchemy● fa.jquery http://docs.formalchemy.org/fa.jquery/● WTForms http://wtforms.simplecodes.com/● colandar https://docs.pylonsproject.org/projects/colander/dev/● deform https://docs.pylonsproject.org/projects/deform/dev/● fanstatic http://www.fanstatic.org/en/0.11.2/index.html