.. meta:: :keywords: web2py, framework, DAL, データベース抽象化レイヤ, コモンフィルタ .. _common_filter: コモンフィルタ ============== コモンフィルタは、テーブルにデフォルトのフィルタ(条件)を設定します。次の様に :meth:`~dal.DAL.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に変更したデータは、フィルタによって外されるようになりました。つまりこの機能は、読み出し時にクエリーの条件に設定しなくても、 自動でデフォルトの条件を設定してくれます。これにより、クエリー式の設定し忘れなどの問題を、回避することができます。 コモンフィルタは、 :ref:`class_table` インスタンスの属性 :attr:`~dal.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 一時的に無効にするには、 :ref:`class_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 です。 この他にフィールドに対するフィルタ、 :ref:`filterin_filterout` があります。 マルチテナント -------------- テーブルに 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 これはデータベース操作時に、アクセスしたホスト名でフィルタをかけるという意味になります。 この機能により、複数のホスト名(ドメイン名)を持ったシステムで、ホスト名により使用データを分けるという意味での、マルチテナントが実現できます。 通常マルチテナントは、 :ref:`common_field` と併せて使用します。つまりホスト名によるフィルタをかけたい一連のテーブル定義の直前に、次の記述を挿入します。 :: db._common_fields.append(Field('request_tenant', default=request.env.http_host,writable=False)) 参考: `Common filters `_ | `コモンフィルタ `_