Odoo を触っていると、角括弧で囲まれた“ドメイン式”をちらほら目にします。アクションボタンや自動化ルール、レコードルール、メールテンプレートの条件設定などで見かけるあのフィルタ条件です。加えて、Odoo の ORM にはこれらの式をそのままフィールドとして扱える専用の Domain フィールド型(fields.Domain)が用意されており、式を構造化されたデータとして保存・表示できる点も覚えておくと便利です。
ドメイン式の扱いは、カスタムモジュールを作る開発者だけでなく、自動化やアクセス制御を設定するビジネスユーザーにとっても重要です。本ガイドでは、Domain フィールドに何が入るのかから、具体的な活用例、実装のコツ、避けるべきミスまでを丁寧に解説します。
Odoo の Domain フィールドとは何か
Odoo における「ドメイン」は、レコード検索のための条件リストです。タプルと論理演算子で記述され、最終的にはデータベースの WHERE 句に変換されて検索に使われます。
典型的なドメイン式の見え方は次のとおりです。
[('customer_rank', '>', 0), ('active', '=', True)]
この式は簡潔に言うと「customer_rank が 0 より大きく、かつ active が True のレコードを返す」という意味です。
Domain フィールド(fields.Domain)は、こうしたドメイン式をレコードの属性として持てるフィールド型です。普通のテキストフィールドと違い、入力の検証や専用の UI ウィジェットが備わっており、コードを書かずに視覚的に条件を組める点が特徴です。
画面上での見え方
画面上では Domain フィールドは自動的にドメインエディタ(ビジュアルフィルタビルダー)で表示されます。ユーザーはフィールドを選び、演算子(等しい、含む、より大きいなど)を選択して値を入力するだけで条件を作成できます。アクセスルールや自動化の条件設定と同じ UI が提供されるため、エンドユーザーでも直感的に扱えます。
データベース上では、ドメインは Python のリストを文字列化した形で格納されます。fields.Domain がシリアライズと検証を透明に扱うため、開発者は Python 側では正しくパースされたドメインを扱い、保存や読み出しはストレージ層に任せられます。
これは Odoo のデータモデリング方針の一例です。フィールドは単なるデータの入れ物ではなく、意味(セマンティクス)、UI 表示、検証ロジックが一体になった定義として扱われます。
フィールドの仕組み
Domain フィールドは Odoo の ORM とフィルタリング機構と深く結びついています。ここでは保存から評価までの流れを概観します。
保存と内部表現について
ドメインを保存するとき、Odoo はそれを文字列として格納します。例えば「現在ユーザーの下書きのみを対象にする」といった動的な条件は文字列化され、実際のクエリ実行時に評価されます。特別変数の uid は実行時に現在のユーザー ID に展開されるため、固定値を書き込む必要はありません。
保存された文字列は Odoo の仕組みで安全に評価され、SQL の WHERE 句に変換されます。この評価は safe_eval を介して行われ、Odoo 固有のコンテキスト変数を扱える制約付きの Python 評価を用います。
ドメインウィジェットについて
UI 上で fields.Domain 型のフィールドはドメインウィジェットで表示されます。ユーザーは条件を追加し、AND/OR を組み合わせて複雑な絞り込みを作り、結果をプレビューすることができます。
このウィジェットのおかげで、ドメインは業務担当者にも扱いやすくなります。文法を覚えなくても視覚的に条件を作れるため、誤入力や設定ミスが減ります。
モデルのコンテキスト設定
Domain フィールドにはモデルコンテキストを設定できます。これによりウィジェットはどのモデルのフィールドを候補にするかを判断します。通常はフィールド定義の model_field 属性でモデル名を参照させます。モデルが指定されない場合、ウィジェットはプレーンテキスト入力にフォールバックしてしまい、ユーザビリティが低下します。
このモデル結びつけは、Odoo フレームワークがフィールド定義と UI 挙動をつなげる基本的な方法です。フィールドがどのモデルを対象にするか知っていることで、インターフェースが適切に振る舞います。
他レコードとの連携
Domain フィールドはリレーションフィールドと組み合わせて、Many2one の候補絞り込みや自動化アクションの対象定義、レポート範囲の指定などに使われます。ドメインは ORM レベルで適用されるため、Odoo のセキュリティやアクセス制御に従って正しくフィルタされます。
業務での利用シーン
Domain フィールドはほぼすべてのモジュールで利用されています。ここでは実務でよく出る 5 つのユースケースを紹介します。
1. 自動化アクションとメールトリガー
自動化(設定 > 技術 > 自動化)でアクションを登録するとき、どのレコードがトリガーかをドメインで指定します。例えば督促メールは「発行済みで未払いかつ期日超過」の請求書だけを対象にする、といった具合です。これらの条件は base.automation の filter_domain という Domain フィールドに保存され、条件にマッチするレコードだけで処理が実行されます。
2. レコードルールとアクセス制御
セキュリティのレコードルールは Domain 式でアクセス可能な行を限定します。営業チーム用のルールなら「所属チームの案件のみ閲覧可」といったドメインを設定し、クエリ実行時に評価されます。こうした行レベルの制御により、コードを追加せずに細かい権限制御が可能です。
3. 在庫・オペレーションの絞り込み
倉庫管理ではリオーダールールやスケジュールされた処理にドメインを使い、特定カテゴリやロケーション、在庫量の条件で処理対象を限定します。例えば再発注は“保管可能且つ在庫が再発注点以下”の製品だけに絞れば、大量の不要処理を防げます。
4. CRM のパイプラインとリード振り分け
CRM ではステージ自動化や活動ルール、リードの割当でドメインを多用します。国や業種、案件規模を元にセールス担当へリードを振り分けるルールはドメインで表現でき、都度コードを書き換えずに画面から調整できます。
5. 動的な Many2one 候補
フォームのカスタム項目で Many2one にドメインを設定すると、表示される候補を絞り込めます。例えば仕入先フィールドを「稼働中で supplier_rank が 0 より大きい」供給元だけにすれば、入力ミスが減り効率が上がります。ドメインは同じフォーム内の他フィールドの値を参照して動的に変化させることも可能です。
フィールドの作成とカスタマイズ方法
Domain フィールドを扱うには大きく分けて 2 つの道があります。Odoo Studio を使ったノーコード設定か、カスタムモジュールで Python/XML を編集する方法です。
Odoo Studio の使い方
現状、Odoo Studio のビジュアルフィールド作成で専用の Domain フィールド型 を直接作る UI は用意されていません。ただし多くの業務設定では不要です。自動化やレコードルール、サーバーアクションに組み込まれたドメインエディタで十分に視覚的に条件を作成できます。
フォーム上の Many2one にドメインを追加したい場合は、Studio のフィールドプロパティでドメイン式を直接入力できます。Studio は基本的な文法チェックを行い、ビュー定義にその式を保存します。
技術的に Python でカスタマイズする場合
カスタムモジュールで Domain フィールドを追加するのは Odoo 開発ガイドラインに沿えば簡単です。以下は典型的な実装例です。
from odoo import models, fields
class MyModel(models.Model):
_name = 'my.model'
model_name = fields.Char(default='res.partner')
filter_domain = fields.Domain(
string='Filter Domain',
model_field='model_name',
help='Domain expression to filter partner records'
)
上の例では model_field 属性でモデル名を参照しています。これによりドメインウィジェットはどのモデルのフィールドを候補にするかを判断します。モデル名を別フィールドで持つことで、ケースによっては対象モデルを動的に切り替えることも可能です。
フォームビューにウィジェットを追加する
フォーム上でドメインビルダーを表示するには、モデル名フィールドとドメインフィールドの両方をビュー定義に含め、ウィジェット指定を行います。
<field name="model_name" invisible="1"/>
<field name="filter_domain" widget="domain"
options="{'model': 'model_name'}"/>
widget="domain" とモデルオプションを省くと単なるテキスト入力として表示されます。ユーザーにドメイン編集を任せる場合は必ず両方を記述してください。
XML-RPC API 経由で値を書く場合
API から Domain フィールドに値を書き込むときは、常に文字列として渡してください。
models.execute_kw(db, uid, api_key, 'my.model', 'write',
[[record_id], {
'filter_domain': "[('active', '=', True)]"
}]
)
Python のリストオブジェクトそのままを渡すと、Odoo のバージョンによってはエラーになったり静かに失敗したりします。API 経由では必ず文字列化してから書き込む習慣を付けましょう。
運用のベストプラクティス
こうした実務上のちょっとした注意が、Domain フィールドと付き合う際のトラブル防止になります。
導入前にドメインの文法をチェックする
無効なドメイン式は Odoo が評価しようとした瞬間にエラーを投げます。自動化やレコードルールに保存する前に検索バーや開発者モードで式を試す、あるいは API の search_count で戻り件数を確認するなど、事前検証を必ず行ってください。
動的変数を活用する
ユーザー ID や会社 ID、日付などを固定値で書くのは避けてください。uid、context_today()、current_company_id といった動的参照を使うことで、別環境への移行や運用変更時の破綻を防げます。
モデルコンテキストの紐付けを忘れない
カスタムモデルに Domain フィールドを追加する際は必ず model_field を設定し、ビューに含めてください。これを怠るとユーザーは視覚的なドメインビルダーを使えず、誤った文字列が保存されるリスクが高まります。
ドメインを読みやすく保つ
| や & を多用したネストされたドメインは可読性が落ち、メンテナンス性が低下します。複雑になりすぎる場合はサーバーアクションや計算フィールドで処理を分けることを検討するか、コード内に注釈を残して意図を明確にしてください。
プログラム的評価には safe_eval を使う
サーバーアクション内などでドメイン文字列を評価する場合は、Python の組み込み eval ではなく Odoo の safe_eval を使ってください。こちらは安全性が高く、Odoo 固有のコンテキスト変数を正しく扱います。
実データでテストする
本番投入前に、実際に近いデータで期待どおりのレコードが返るかを必ず確認してください。自動化や権限周りのフィルタが間違っていると、誤った処理やアクセス遮断が起きても気付きにくくなります。
よくある落とし穴
最後に、Domain フィールドで陥りがちなミスとその回避法を整理します。
フィールド型とドメイン式を混同する
Odoo では「ドメイン」がふたつの意味で使われます。ひとつはフィルタ文法そのもの(タプルの並び)、もうひとつはその式を格納する fields.Domain 型のフィールドです。カスタマイズ初心者はしばしば混同します。Domain フィールドはあくまで式を入れる容器であり、式そのものはその中身です。
API にリストを渡してしまう
XML-RPC 経由で Domain フィールドに書き込む際、Python のリストをそのまま渡すと型エラーや無視されるといった問題になります。必ず文字列にシリアライズして送信してください。
ウィジェットでモデルコンテキストを欠く
フォームに Domain フィールドを配置してもウィジェットの options にモデル参照が無いと、ユーザーはプレーンテキスト入力しか使えません。モデル参照を明確に指定することを忘れないでください。
レコード ID を直書きする
ドメインの中に具体的なレコード ID をハードコードすると、そのレコードが削除されたり別 DB に移したときに silently 壊れます。uid やリレーション検索など動的参照を使ってポータビリティを保ちましょう。
レコードルールのドメインが広すぎる/狭すぎる
権限ルールの条件が緩過ぎると不適切に情報が見えてしまい、厳し過ぎると正当なユーザーのアクセスが遮断されます。必ず対象ユーザー視点でテストしてください。管理者アカウントは多くのルールをバイパスするため、管理者での確認だけでは不十分です。
アーカイブされたレコードを忘れる
既定で Odoo はアーカイブ済み(active = False)を検索から除外します。アーカイブも含めたい場合は ('active', 'in', [True, False]) のように明示してください。そうしないとデータの欠損に見舞われることがあります。
まとめ
Domain フィールドは Odoo の多くの機能に静かに力を与える重要な構成要素です。アクセス制御や自動化、動的ドロップダウンやダッシュボードの絞り込みまで、レコードのフィルタリングの中心にあるのがドメイン式であり、fields.Domain はその式を検証付きでモデルに組み込む手段を提供します。
業務ユーザーにとってはドメインウィジェットがコード不要で条件設定を可能にし、開発者にとっては従来 Char とウィジェットの組み合わせで曖昧になりがちだった定義を明確にします。Odoo Studio、カスタムモジュール、あるいは UI 上の自動化設定いずれであっても、Domain フィールドを理解しておくと応用の幅が広がります。
本稿で紹介した考え方は Odoo のバージョンやモジュールを超えて応用できます。ドメイン周りに時間を投資する価値は高く、学んでおくと日々の運用やカスタマイズがずっと楽になります。
Odoo 導入の支援が必要ですか?
Dasolo は企業向けに Odoo の導入、カスタマイズ、最適化を支援します。自動化フローの設計やカスタムモジュール作成、既存環境の改善など、実務に即した技術力でプロジェクトを前に進めます。
Domain フィールドや Odoo に関するご質問があれば、 お気軽にお問い合わせください。当社で御社のセットアップを拝見し、次の一手をアドバイスいたします。