はじめに
Odooでリードの優先度を選んだり、支払方法を指定したり、商品を有効/非表示にしたりする場面――これらの多くはSelectionフィールドを通じて行われます。UI上ではごくシンプルに見えますが、データの一貫性を保ち、集計や自動化の基盤になる重要なフィールドタイプです。
Selectionフィールドは自由入力を許さず、あらかじめ定めた候補の中からしか値を受け付けません。この制約がデータのばらつきやタイプミスを防ぎ、検索・集計・レポートの精度を保つ肝になります。
本ガイドでは、Selectionフィールドが内部でどんな値を保持するか、画面上でどのように表示されるか、Odoo Studio・Pythonモジュール・XML-RPC経由での作り方までを網羅します。実務に即した利用例や避けるべきミスもあわせて紹介します。
OdooのSelectionフィールドとは何か
OdooのORMでは、Selectionフィールドは固定の選択肢リストから選ばれた文字列(キー)を格納します。選択肢は内部キーと画面表示ラベルの組み合わせで定義され、データベースにはキーだけが保存されます。
たとえば、優先度を管理するフィールドを考えてみましょう。
priority = fields.Selection([
('0', '通常'),
('1', '低い'),
('2', '高い'),
('3', '緊急'),
], string='優先度', default='0')
この例では'0'〜'3'がDBに保存されるキーで、通常や高いがユーザーに見えるラベルです。ラベルは後で自由に変えられますが、キーは既存レコードとの互換性のために慎重に扱う必要があります。
画面上ではフォームではドロップダウン、リストではラベル表示になります。badgeウィジェットを使えば色付きのタグとして表示でき、一覧やカンバンで視認性が格段に上がります。
Odoo Studio上ではこのフィールドはSelectionとして扱われ、作成すると自動でx_studio_接頭辞が付与されます。コードやAPIで作る場合は任意の技術名を付けられます。
Selectionフィールドの仕組み
データベース側ではSelectionはPostgreSQLのVARCHAR列として保存され、ラベルではなくキーだけが格納されます。ドメインやサーバー処理では必ずキーを使って判定する点に注意してください。
たとえば優先度が『高い』のリードを検索する場合、ドメインは[('priority','=', '2')]のようにキーを指定します。'High'などの表示ラベルで検索してもヒットしません。
重要な属性
Selectionフィールドを定義するときに覚えておくべき主要プロパティは次のとおりです。
- selection:利用可能な選択肢を
(key, label)のタプルで定義します。関数名(文字列)を渡して動的にリストを返すことも可能です。 - default:値が未設定のときに使われる既定キー。指定しなければ空になります。
- required:保存時に必須にするフラグ。既定値と組み合わせてステータス系のフィールドに使うことが多いです。
- selection_add:既存フィールドに対してモジュール継承で選択肢を追加するための仕組み。元リストを丸ごと上書きせずに拡張できます。
- ondelete:モジュールがアンインストールされたときに、追加した選択肢を使っているレコードに対してどんな処理を行うか指定します。
静的リストと動的リストの違い
通常は選択肢リストを静的に宣言しますが、selectionにメソッド名を渡すことで実行時に選択肢を生成することもできます。これにより、ユーザー権限や会社ごとに異なる選択肢を表示するといった柔軟な制御が可能です。
contract_type = fields.Selection(
selection='_get_contract_types',
string='契約種別'
)
def _get_contract_types(self):
if self.env.user.has_group('hr.group_hr_manager'):
return [('permanent', '正社員'), ('fixed', '有期雇用'), ('interim', '派遣')]
return [('permanent', '正社員'), ('fixed', '有期雇用')]
ビューでの見え方
フォームではドロップダウン表示が基本です。リストやカンバンではwidget="badge"で色付きラベル、選択肢が少ない場合はwidget="radio"でラジオボタン表示にして一覧性を高めるのが有効です。
ORMとのやり取り
ORMでの読み書きは単純で、値にはキーを直接代入します。XML-RPCのfields_getでフィールド情報を取ると、selectionに[key,label]ペアの一覧が含まれるため、外部システムで表示ロジックを組めます。
業務での利用場面
Selectionフィールドは標準モジュールの中で至るところに使われています。ここでは実務でよく出てくる具体例を紹介します。
CRM:リード優先度や商談フェーズの種別
CRMでは優先度や商談フェーズのタイプがSelectionで管理されます。営業は優先度で注力度合いを変え、カンバンの色分けや自動化ルールに反映させます。運用開始後に優先度分布を調整するだけでデータ品質が大きく改善することが多いです。
販売:支払条件や請求ポリシー
製品のinvoice_policyはSelectionで「受注ベース」か「出荷ベース」かを決め、請求フロー全体を左右します。サブスクリプションの課金モード(前払い/後払い)も同様で、こうしたフィールドは財務処理に直接影響します。
在庫:製品・ロットの品質ステータス
製造・品質管理ではロットやシリアル、修理指示のステータスをSelectionで管理します。修理の状態が遷移するたびにメール送信や在庫移動、会計伝票を起こせるようにしておけば、ワークフロー全体の制御点として機能します。
会計:支払方法とジャーナルタイプ
会計のジャーナル種別もSelectionで管理され、売上・仕入・現金・銀行などに応じた仕訳ロジックや操作制限が適用されます。ラベル付けだけでなく業務ルールを制御する典型例です。
人事:雇用形態や契約ステータス
HRでは雇用種別や契約の状態、休暇申請のステータスにSelectionを使います。契約期限の通知やオンボーディング、給与計算ルールの切替など、選択肢が変わると自動化・通知が連動する場面が多くあります。
Selectionフィールドの作成・カスタマイズ方法
Selectionフィールドを追加する方法は主に三つあり、導入形態やバージョン管理の要否によって使い分けます。
Odoo Studioを使う(ノーコード)
Odoo Studioはコードを書かずにフィールド追加が行えるローコードツールです。StudioでSelectionを作る手順は次のとおりです。
- メインメニューからOdoo Studioを開く。
- フィールドを追加したいフォーム画面へ移動する。
- サイドバーからSelectionフィールドをフォームにドラッグする。
- フィールドプロパティで各選択肢のラベルを入力する。
- 必要なら既定値を設定し、必須にするか指定する。
- 保存してStudioを閉じる。
Studioで作成されたフィールドは自動生成キーと入力したラベルが紐付く形でx_studio_接頭辞が付きます。要件確認やクライアントとのセッション中に素早く追加できるため短期間の調整に便利です。
カスタムモジュールでPythonを使う方法
開発者がモジュール内で定義する場合、SelectionはPythonのモデル定義として書きます。複数環境で配布し、コード管理したい変更はこの方法が推奨されます。
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_delivery_slot = fields.Selection([
('morning', '午前(8時〜12時)'),
('afternoon', '午後(13時〜17時)'),
('evening', '夕方(18時〜20時)'),
], string='配送枠', default='morning')
フィールド定義後は該当ビューのXMLに追加して画面表示させます。モジュールをインストールまたはアップグレードするとOdooがDB列を自動で作成します。
既存フィールドに選択肢を追加する際は、フィールド全体を再定義する代わりにselection_addを使います。
class SaleOrder(models.Model):
_inherit = 'sale.order'
state = fields.Selection(
selection_add=[('custom_approval', '承認待ち')],
ondelete={'custom_approval': 'set default'}
)
XML-RPC APIを使う方法
デプロイパイプラインやリモート設定スクリプトから自動的にフィールドを作る場合、XML-RPC経由でSelectionフィールドを作成できます。
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_contract_category',
'field_description': '契約カテゴリー',
'model_id': model_id,
'ttype': 'selection',
'selection': "[('standard', '標準'), ('premium', 'プレミアム'), ('custom', 'カスタム')]",
'state': 'manual',
}]
)
API経由で作る場合、selectionはPythonリストの文字列表現として渡します。state: 'manual'はStudioやAPIで手動作成されたフィールドを示す正しい設定です。自動化スクリプトで遠隔作成する際の一般的な手法です。
運用のベストプラクティス
1. 意味のある安定したキーを使う
キーはDBに保存され、ドメインや自動化ロジックで直接参照されます。後から変えると互換性が壊れるため、短く意味が分かる英字キー(例:'draft'、'confirmed')を採用しましょう。連番の数字キーは読みづらくなるので原則避けます。
2. 選択肢は短く完結に保つ
選択肢が8〜10以上に増えると本来の用途を超えている可能性があります。その場合は選択肢を管理する別モデル(Many2one)に切り替える検討をしましょう。ユーザー自身で編集できる仕組みにすると運用が楽になります。
3. 必須フィールドには既定値を設定する
必須にするなら妥当なデフォルトを設けておきます。APIやインポート経由でレコードが作成される際に選択漏れでエラーになるのを防げます。既定値は最も一般的、または状態の変更が少ないものを選びます。
4. ネイティブフィールド拡張はselection_addを使う
既存Odooフィールドに選択肢を追加する場合はselection_addを用い、ondeleteでアンインストール時の挙動を定義してください。これにより他モジュールとの互換性が保てます。
5. 一覧での視認性向上にはbadgeを使う
リストやカンバンで通常のテキスト表示だと視認性が落ちます。ビューXMLでwidget="badge"を使うと色付きラベルになり、ステータスの一覧把握がしやすくなります。
よくある落とし穴
キーを変更すると既存データが壊れる
ラベルは後で安全に変更できますが、キーを後から変えると既存レコードは無効値になり、ドメインや自動化ルールも動作しなくなります。キーを変更する場合は事前にデータマイグレーションで既存レコードを更新してください。
選択肢を削除すると該当レコードが孤立する
まだ使われているキーを選択肢から取り除くと、その値を持つレコードは表示が崩れます。削除前に該当レコードを検索して別値へ更新するかアーカイブするなどの対処が必要です。
ラベルでフィルタを書くミス
GUIで自動化条件を作るとき、表示ラベルでフィルタを書いてしまうことがよくあります。これはゼロ件ヒットを生むだけでエラーにならないため原因の特定が難しくなります。ドメイン作成時は必ずキーを確認してください。
Selectionを使うべきでないケース
選択肢が頻繁に変わる、ユーザー自身で管理させたい、色や順番、追加属性が必要な場合はMany2oneで設定モデルを作る方が適しています。Selectionは安定した開発者管理型リストに向きます。
サーバー側処理で空値を扱わないミス
必須でないSelectionは値がないとFalseになることがあります。サーバー処理や自動化で文字列と比較する前にFalseチェックを入れないと意図しない挙動になります。空値を明示的に扱う実装を心がけましょう。
まとめ
Selectionは一見単純でも奥が深いフィールドです。キーとラベルの違い、selection_addの使い分け、Many2oneにすべき場面を理解することが、使いやすく長持ちするOdoo設計と運用の分かれ道になります。
Odoo Studioでの簡易追加から、Pythonモジュールでの厳密な定義、APIを使った自動作成まで、本稿で扱ったパターンを押さえれば多くのケースで適切な選択ができるようになります。
Odooのデータモデルにおいて、Selectionフィールドは入力段階でデータ品質を担保する主要な仕組みの一つです。適切に使えばレコードは整い、レポートは正確になり、自動化は信頼できるものになります。
Dasoloでは企業のOdoo導入・カスタマイズ・最適化を支援しています。クリーンなデータモデル設計、業務フローへのフィールド追加、フルモジュール開発など、幅広くサポート可能です。 お問い合わせはこちら あなたのOdooプロジェクトについてぜひお話ししましょう。