SQLFORM.factory

□未翻訳

□翻訳中

■翻訳完了(細田謙二)

■レビュー(Omi Chiba)

SQLFORM.factory

データベース・テーブルを持っているかのようにフォームを生成したいが、データベース・テーブルはいらないような場面があります。見栄えのよいCSSフレンドリなフォームの生成と、おそらくファイルのアップロードとリネームの実行のために、SQLFORMの能力を単純に活用したい場面です。

There are cases when you want to generate forms as if you had a database table but you do not want the database table. You simply want to take advantage of the SQLFORM capability to generate a nice looking CSS-friendly form and perhaps perform file upload and renaming.

これはform_factoryを介して行うことができます。ここに、フォームを生成し、検証を行い、ファイルをアップロードし、すべてをセッションに保存するような例を示します。

This can be done via a form_factory. Here is an example where you generate the form, perform validation, upload a file and store everything in the session :

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

def form_from_factory():

form = SQLFORM.factory(

Field('your_name', requires=IS_NOT_EMPTY()),

Field('your_image', 'upload'))

if form.accepts(request.vars, session):

response.flash = 'form accepted'

session.your_name = form.vars.your_name

session.filename = form.vars.your_image

elif form.errors:

response.flash = 'form has errors'

return dict(form=form)

次にビュー"default/form_from_factory.html"を示します:

Here is the "default/form_from_factory.html" view:

1.

2.

{{extend 'layout.html'}}

{{=form}}

フィー ルドのラベルにおいてスペースの代わりにアンダースコアを使用するか、SQLFORMで行ったのと同様に、labelsの辞書をform_factory に明示的に渡す必要があります。デフォルトでは、SQLFORM.factoryは、あたかも"no_table"というテーブルから生成されたフォーム のように生成されたhtmlの"id"属性を用いてフォームを生成します。このダミーテーブルの名前を変更したいときは、factoryのtable_name属性を用いてください:

You need to use an underscore instead of a space for field labels, or explicitly pass a dictionary of labels to form_factory, as you would for a SQLFORM. By default SQLFORM.factory generates the form using html "id" attributes generated as if the form was generated from a table called "no_table". To change this dummy table name, use the table_name attribute for the factory:

1.

form = SQLFORM.factory(...,table_name='other_dummy_name')

factoryから生成された2つのフォームを同じテーブルに配置する必要があり、かつ、CSSの競合を避けたい場合、table_nameの変更が必要になります。

複数のテーブルに対する1つのフォーム

One form for multiple tables

しばしば起こるのは、2つのテーブル(たとえば、参照によって互いにリンクした'client'と'address')を持ち、1つのclientとそのデフォルトのアドレスに関する情報を挿入できるような単一のフォームを作りたい場面です。以下に方法を記述します:

It often happens that you have two tables (for example 'client' and 'address' which are linked together by a reference and you want to create a single form that allows to insert info about one client and its default address. Here is how:

モデル:

model:

1.

2.

3.

4.

5.

db.define_table('client',

Field('name'))

db.define_table('address',

Field('client',db.client,writable=False,readable=False),

Field('street'),Field('city'))

コントローラ:

controller:

1.

2.

3.

4.

5.

6.

7.

8.

def register():

form=SQLFORM.factory(db.client,db.address)

if form.accepts(request.vars):

id = db.client.insert(**db.client._filter_fields(form.vars))

form.vars.client=id

id = db.address.insert(**db.address._filter_fields(form.vars))

response.flash='Thanks for filling the form'

return dict(form=form)

SQLFORM.factoryに注目してください(これは"1つ"のフォームを両者の公開されたフィールドから作成し、それらのバリデーターもまた受け継いでいます)。フォームが受理されたとき、これは2つの挿入を行います。いくつかのデータは片方のテーブルに、またいくつかのデータはもう片方に行きます。

Notice the SQLFORM.factory (it makes ONE form using public fields from both tables and inherits their validators too). On form accepts this does two inserts, some data in one table and some data in the other.

これは、複数のテーブルが共通のフィールド名を持っていないときのみ機能します。

This only works when the tables don't have field names in common.