2.5. コモンフィルタ

コモンフィルタは、テーブルにデフォルトのフィルタ(条件)を設定します。次の様に define_table() の common_filter パラメータに設定します。

db.define_table('person',
        Field('name'),
        Field('is_active','boolean',default=True),
        common_filter = lambda query: db.person.is_active==True)

この場合、db.person.is_active==True とフィルタが設定されます。実際のデータで試してみましょう。

>>> print db(db.person).select()
person.id,person.name,person.is_active
1,Damapoda,True
2,Socosapo,True
3,Saduduco,True

次のようにデータを変更してから、テーブルのデータを一覧表示させます。

>>> db.person[3]=dict(is_active=False)
>>> print db(db.person).select()
person.id,person.name,person.is_active
1,Damapoda,True
2,Socosapo,True

is_activeフィールドをFalseに変更したデータは、フィルタによって外されるようになりました。つまりこの機能は、読み出し時にクエリーの条件に設定しなくても、 自動でデフォルトの条件を設定してくれます。これにより、クエリー式の設定し忘れなどの問題を、回避することができます。

コモンフィルタは、 Table インスタンスの属性 _common_filter に格納されます。このため、テーブル定義時以外でも変更可能です。 例えば、コモンフィルタを無効にする場合は、None を指定します。

>>> db.person._common_filter = None
>>> print db(db.person).select()
person.id,person.name,person.is_active
1,Damapoda,True
2,Socosapo,True
3,Saduduco,False

一時的に無効にするには、 Set クラスのインスタンス作成時に、パラメータ ignore_common_filters に True を渡します。

>>> print db(db.person, ignore_common_filters=True).select()
person.id,person.name,person.is_active
1,Damapoda,True
2,Socosapo,True
3,Saduduco,False

このパラメータのデフォルト値は False です。

この他にフィールドに対するフィルタ、 fiter_in と filter_out があります。

2.5.1. マルチテナント

テーブルに request_tenant という名前のフィールドが存在すると、コモンフィルタは特殊な動作をします。 具体的に次のようなフィールド定義がテーブルにあると仮定します。

db.define_table('person',
        Field('name'),
        Field('request_tenant', default=request.env.http_host, writable=False))

ここでは明示的にコモンフィルタは設定されていません。しかしweb2pyは request_tenant フィールドの存在を確認し、 次のような条件を、コモンフィルタに自動で追加します。

db.table.request_tenant == db.table.request_tenant.default

ここで db.table.request_tenant.default はフィールド定義で request.env.http_host となっているため、次の条件式になります。

db.table.request_tenant == request.env.http_host

これはデータベース操作時に、アクセスしたホスト名でフィルタをかけるという意味になります。 この機能により、複数のホスト名(ドメイン名)を持ったシステムで、ホスト名により使用データを分けるという意味での、マルチテナントが実現できます。

通常マルチテナントは、 コモンフィールド(フィールドの継承) と併せて使用します。つまりホスト名によるフィルタをかけたい一連のテーブル定義の直前に、次の記述を挿入します。

db._common_fields.append(Field('request_tenant',
        default=request.env.http_host,writable=False))

参考: Common filtersコモンフィルタ