多対多、list:<type>、contains

□未翻訳

□翻訳中

■翻訳完了(細田謙二)

■レビュー(Omi Chiba)

多対多、list:<type>、contains

web2pyは、以下の特別なフィールド型を用意しています:

web2py provides the following special field types:

1.

2.

3.

list:string

list:integer

list:reference <table>

これらはそれぞれ、文字列、整数、参照のリストを収容します。

They can contain lists of strings, of integers and of references respectively.

Google App Engineでは、list:stringはStringListPropertyにマッピングされ、他の2つは、ListProperty(int)にマッピングされます。リレーショナル・データベースでは、|によって区切られた項目のリストを持つテキストフィールドにマッピングされます。たとえば、[1,2,3]は|1|2|3|にマッピングされます。

On Google App Engine list:string is mapped into StringListProperty, the other two are mapped into ListProperty(int). On relational databases they all mapped into text fields which contain the list of items separated by |. For example [1,2,3] is mapped into |1|2|3|.

文字列のリストでは、項目内の任意の|が||に置換されるように項目はエスケープされます。いずれにせよ、これは内部表現でありユーザーに対しては透過的です。

For lists of string the items are escaped so that any | in the item is replaced by a ||. Anyway this is an internal representation and it is transparent to the user.

次の例のようにlist:stringを用いることができます:

You can use list:string, for example, in the following way:

1.

2.

3.

4.

5.

6.

7.

8.

9.

>>> db.define_table('product',

Field('name'),

Field('colors','list:string'))

>>> db.product.colors.requires=IS_IN_SET(('red','blue','green'))

>>> db.product.insert(name='Toy Car',colors=['red','green'])

>>> products = db(db.product.colors.contains('red')).select()

>>> for item in products:

print item.name, item.colors

Toy Car ['red', 'green']

list:integerも同様に機能します。ただし、項目は整数でなければなりません。

list:integer works in the same way but the items must be integers.

例のごとく、この要求は、insertレベルではなく、フォームレベルで強制されます。

As usual the requirements are enforced at the level of forms, not at the level of insert.

list:<type>フィールドにおいて、contains(value)演算子は、valueが含まれているかをリストに対してチェックする自明でないクエリにマッピングされます。contains演算子は標準のstringとtextフィールドでも機能し、LIKE '%value%'にマッピングされます。

For list:<type> fields the contains(value) operator maps into a non trivial query that checks for lists containing the value. The contains operator also works for regular string and text fields and it maps into a LIKE '%value%'.

list:referenceとcontains(value)演算子は、多対多リレーションの非正規化にとって特に有用です。以下がその例です。

The list:reference and the contains(value) operator are particularly useful to de-normalize many-to-many relations. Here is an example:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

>>> db.define_table('tag',Field('name'),format='%(name)s')

>>> db.define_table('product',

Field('name'),

Field('tags','list:reference tag'))

>>> a = db.tag.insert(name='red')

>>> b = db.tag.insert(name='green')

>>> c = db.tag.insert(name='blue')

>>> db.product.insert(name='Toy Car',tags=[a, b, c])

>>> products = db(db.product.tags.contains(b)).select()

>>> for item in products:

print item.name, item.tags

Toy Car [1, 2, 3]

>>> for item in products:

print item.name, db.product.tags.represent(item.tags)

Toy Car red, green, blue

list:referenceのtagフィールドは次のようなデフォルトの制約を得ることに注意してください

Notice that a list:reference tag field get a default constraint

1.

requires = IS_IN_DB(db,'tag.id',db.tag._format,multiple=True)

これは、フォームにおいてSELECT/OPTIONの複数ドロップボックスをを生成します。

that produces a SELECT/OPTION multiple drop-box in forms.

また、このフィールドはデフォルトで、書式化した参照のカンマ区切りのリストとして参照リストを表現するrepresent属性を得ることにも注意してください。これは、フォームとSQLTABLEの読み込み時に利用されます。

Also notice that this field gets a default represent attribute which represents the list of references as a comma-separated list of formatted references. This is used in read forms andSQLTABLEs.

list:referenceはデフォルトのバリデータとデフォルトの表現を持つ一方、list:integerとlist:stringは持ちません。したがって、これら2つに関しては、フォームにおいてそれらを利用する場合、IS_IN_SETかIS_IN_DBバリデータが必要になります。

While list:reference has a default validator and a default representation,list:integer and list:string do not. So these two need an IS_IN_SET or anIS_IN_DB validator if you want to use them in forms.