イントロダクション
販売注文で数量を入力したり、タスクの経過日数を記録したり、見込み客に点数を付けたりした経験があれば、あなたはすでにOdooのIntegerフィールドを使っています。Odooのデータ設計で最も出現頻度の高いフィールドの一つですが、その性質を軽視されがちです。
Integerフィールドの挙動を理解することは、フォームを設定する業務担当者、カスタムモジュールを作る開発者、クライアント向けにデータ設計を行うコンサルタントのいずれにとっても重要です。
本ガイドでは、Integerフィールドが何を保持するのか、Odooのフレームワークや画面でどのように振る舞うのか、Odoo StudioやPythonでの作成方法、実用的なユースケース、注意点までを網羅します。
OdooのIntegerフィールドとは何か
OdooのORMでは、Integerフィールドは小数を許さない“整数”だけを格納するために設計されています。データベース上ではPostgreSQLのINTEGER列に対応し、-20億台から+20億台までの値を扱えます。
ユーザー側から見ると、Integerはフォーム上のシンプルな数値入力欄や一覧の数字カラムとして表示されます。個数、スコア、日数、連番など“半分”が意味をなさない計測には最適です。
典型的なPythonでの定義例を示します。
from odoo import fields, models
class ProjectTask(models.Model):
_inherit = 'project.task'
estimated_hours = fields.Integer(
string='Estimated Hours',
default=0,
)
パラメータのうちstringは画面に表示されるラベルを決め、defaultは新規レコード作成時に自動で入る初期値を設定します。
Odoo Studioではこのフィールドは単にIntegerと表示され、Studioで作ると自動的にx_studio_接頭辞が付きます。PythonやAPIで作る場合は技術名を自分で決めます。
フィールドの動作原理
Integerフィールドを定義すると、モジュールのインストールやアップグレード時にフレームワークが対応するDB列を自動生成します。手動でSQLマイグレーションを書く必要はありません。
データベース上の列はPostgreSQLでINTEGER型になります。Odoo ORMが型変換を担うため、空入力時にNoneやFalseではなく0が返る点が他のフィールド型と異なります。これは設計上の重要な差異です。
主要なフィールド属性
Integerフィールドで設定できる重要なプロパティを整理します。
- string:画面に表示するラベル。
- default:新規作成時に自動的に入る値。未指定時は
0が既定です。 - required:必須にするオプション。既定値が
0であるため、ゼロを許容しない検証をしたい場合に有効です。 - readonly:画面上で編集させたくない場合に設定します。
- index:列にインデックスを作成し、検索やフィルタを高速化します。
- compute:他フィールドから算出するためのPythonメソッドを紐づけます。
- store:
computeと合わせて、計算結果をDBに保存するかどうかを制御します。 - copy:レコード複製時に値を引き継ぐかを決めます。
- groups:特定のユーザーグループだけに見せる制御を行えます。
ビューでの見え方
フォームでは数値入力欄として表示され、大きな数字には自動的に千区切りが付くことが多く可読性が上がります。
一覧(リスト)では右寄せで表示されるのが慣例です。検索では等しい/より大きい/より小さいといった比較フィルタが機能します。
ビュー上でウィジェットを使えば見た目を変えられます。例えばpriorityウィジェットは星評価のようにし、progressbarウィジェットは最大値を設定すると進捗バーとして表示できます。
ORMとのやり取り
開発者目線では読み書きがシンプルで、常にPythonのint型が返ります。空の状態は0として扱われるため、“値が未設定かどうか”を条件で判定する際は注意が必要です。
Integerはcomputedフィールドやビューのドメイン、サーバーアクション、他の自動化処理で自然に使えます。
業務での利用シーン
Odooの多くのモジュールで頻繁に登場するため、代表的なユースケースをいくつか示します。
1. CRM:リードスコア
営業ではリードの優先度付けにスコアを使います。CRMの商談モデルにカスタムのIntegerフィールド「リードスコア」を追加し、手動で更新するか自動計算で割り当てる運用が一般的です。
スコアでパイプラインを並べ替えれば、有望な案件に集中しやすくなります。
2. 販売:最小注文数量
商品や価格表の最小注文数をIntegerで管理すると、注文入力時に下限未満の数量をブロックでき、顧客とのやり取りを減らせます。
3. 在庫:補充ルール(再発注)
在庫の最小・最大在庫はIntegerで定義されます。最小を下回るとOdooが自動で補充発注をかけ、最大まで補充する仕組みです。適切な閾値設定は欠品と過剰在庫の回避に直結します。
4. プロジェクト管理:ストーリーポイントや工数見積り
プロジェクト業務ではタスクにストーリーポイントや見積工数(整数)を持たせ、カンバンや一覧でチームのキャパシティやベロシティを可視化します。
5. 会計:支払期限の日数
会計の支払条件は支払猶予日数をIntegerで表現します。Net30やNet60といった設定が請求書の支払期日計算に使われ、資金繰りに影響します。
Integerフィールドの作成・カスタマイズ方法
Integerフィールドを追加する方法は主に2つ:コーディング不要のOdoo Studioと、より細かい制御が可能なPython定義です。
Odoo Studioを使う場合
Odoo Studioはコードを書かずにフィールドやビューをカスタマイズできるツールです。StudioでIntegerを追加する手順は次のとおりです。
- 追加したいフォームを開きます。
- 右上のメニューからStudioを有効化します。
- 左側のフィールドリストからIntegerをドラッグしてフォームに配置します。
- ラベル、必須設定、初期値などを設定します。
- 設定を保存してStudioを終了します。
Studioで作成したフィールドは自動的にx_studio_接頭辞が付き、定義はir.model.fieldsに保存されます。作成後すぐにフォームや一覧で利用可能です。
Pythonで定義する場合(技術的なカスタマイズ)
より細かい制御やモジュール開発をする開発者は、モデルクラスに直接Integerフィールドを定義します。
from odoo import fields, models
class CrmLead(models.Model):
_inherit = 'crm.lead'
x_lead_score = fields.Integer(
string='Lead Score',
default=0,
index=True,
help='Score from 0 to 100 used to prioritize opportunities',
)
コードで定義したらodoo-bin -u your_moduleを実行してDBへ反映します。対応するカラムは自動生成されます。
XML-RPC APIを使う場合
サーバーに直接アクセスできない環境や自動デプロイの場面では、XML-RPC API経由でフィールドを作成することも可能です。
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_lead_score',
'field_description': 'Lead Score',
'model_id': crm_lead_model_id,
'ttype': 'integer',
'state': 'manual',
}]
)
Integerフィールドのttypeは'integer'で、カスタムフィールドであることを示すにはstateを'manual'にします。
計算済み(computed)のIntegerフィールドを追加する
計算フィールドは自動で値を導出するのに便利です。例えばプロジェクトに紐づく未完了タスク数を数える例を示します。
class Project(models.Model):
_inherit = 'project.project'
open_task_count = fields.Integer(
string='Open Tasks',
compute='_compute_open_task_count',
store=True,
)
def _compute_open_task_count(self):
for project in self:
project.open_task_count = self.env['project.task'].search_count([
('project_id', '=', project.id),
('stage_id.fold', '=', False),
])
ここでstore=Trueにすると計算結果がDBに保存され、一覧でのフィルタやソートに使えるようになります。再計算の頻度やパフォーマンスを考えて使い分けましょう。
ベストプラクティス
Integerフィールドを効果的に使うための実践的なアドバイスをまとめます。
カウントや単位が整数である場合にIntegerを使う
値が必ず整数であることが確定している用途に使ってください。通貨や小数を扱う測定にはFloatやMonetaryを選ぶべきです。
適切な初期値を設定する
デフォルトは0ですが、0が意味を持つケースかを検討してください。未設定と0を区別したい場合は、補助のBooleanフィールドを用意するなど設計を工夫しましょう。
頻繁にフィルタするならインデックスを付ける
検索や集計で多用するフィールドにはindex=Trueを付けると大規模データでも高速に動きます。インデックスはわずかなストレージ増と書込コストを伴いますが、検索性能の向上効果は大きいです。
計算フィールドはstore=Trueを検討する
一覧やドメインで絞り込みやグルーピングに使う計算値は必ずDBに保存する設定にすると運用がスムーズです。
有効範囲をドキュメント化する
スコアが0〜100など意味のあるレンジを持つ場合は、helpに説明を入れておくと利用者の誤入力を減らせます。
ID参照をIntegerで扱わない
別レコードへの参照はIntegerで生のIDを入れるのではなく、Many2oneを使ってください。ナビゲーションや連鎖削除、ORMの恩恵を受けられます。単純なIDだけを持つIntegerは保守性が低くなります。
よくある落とし穴
Integerフィールドを使う際に陥りやすいミスを挙げます。
IntegerとFloatを混同する
小数が入りうる値をIntegerで扱うと、入力された小数が切り捨てられてデータ欠損につながります。72.5%のような値が必要なら最初からFloatを選びましょう。
ゼロを“空”と誤解する
Integerは未設定でも0を返すため、未入力と意図的な0を区別できません。両者を区別する必要がある場合は補助フラグを用意するか型を検討してください。
頻繁に使うフィールドにインデックスを付け忘れる
後からパフォーマンス問題になることが多いので、検索で多用する予定があるなら最初からindex=Trueを考慮してください。
小数表現の比率をIntegerで保管する
百分率を75で表す運用は簡単ですが、小数が必要になった瞬間に破綻します。比率に小数が入りうるならFloatを選ぶべきです。
フィルタで使う計算フィールドにstore=Trueを付けない
計算フィールドをフィルタやグループ化に使うなら必ず保存する設定にしないと、期待通りに動作しません。ここはOdoo開発で最もよくある落とし穴の一つです。
まとめ
IntegerフィールドはOdooデータ設計の基本中の基本です。一見単純ですが、空値が0で返ることや、計算フィールドは保存設定が必要などの振る舞いを理解しておかないと、後で修正が難しい問題を招きます。
営業設定、カスタムモジュール、倉庫の再発注ルール設計など、Odooに関わるあらゆる場面でIntegerは登場します。FloatやMonetaryとの使い分けを含め、正しい理解が安定した導入につながります。
Odooのカスタマイズを始めるときに、初期段階でデータモデルを正しく設計しておくことはプロジェクト全体の保守性と安定稼働に大きな利得をもたらします。基礎を押さえる価値は高いです。
Odooの専門家と一緒に進めるには
私たちDasoloは、業界や業務に合わせたOdooの導入、カスタマイズ、最適化を支援しています。データモデル設計、カスタムフィールドやワークフローの構築、外部システムとの連携まで、実務経験に基づいた実装でお手伝いします。
Odooの設定でお悩みがある、あるいはプロジェクトについて相談したい場合は、 ぜひ当チームまでお問い合わせください。お気軽にご相談ください。私たちがサポートします。