Odooの読み取り専用フィールドは、一見ただの“編集不可”表示に見えますが、業務フローの整合性や会計監査、在庫管理などで非常に重要な役割を果たします。
画面上で項目がグレーアウトしている理由を知りたい業務担当者も、表示挙動を細かく制御したい開発者も、本ガイドで必要なポイントを網羅できます。
どの時点でユーザーが値を変更できるかを明確にしておけば、データの一貫性が保たれ、つまずきが少ない業務プロセスを作れます。
このチュートリアルはビジネス側の使い方と技術側の実装両面を扱うので、設定者も開発者も実務で使える知識が得られます。
Odooでの「読み取り専用(readonly)」フィールドとは何か
Odooにおける読み取り専用フィールドとは、値は表示されるがユーザーが画面上で直接編集できないフィールドです。見えているが入力がロックされている状態を指します。
フォームビューでは、読み取り専用フィールドは通常テキスト表示になり、入力欄ではありません。テーマによっては薄く表示されたり、単に編集可能なフィールドと視覚的に区別されます。
読み取り専用はOdoo内で二つのレイヤーに適用できます。
- モデル(Python/ORM)レベルでの指定:フィールド自体に恒久的な読み取り専用属性を与える方法。
- ビュー(XML)レベルでの指定:特定のビューや条件下でのみ読み取り専用にする方法。
この違いは重要です。ORMレベルでreadonlyにしたフィールドはUIから一切編集できません。一方、ビューでreadonlyにすると、そのビューの文脈だけで保護され、別のビューやサーバー側の処理では書き込み可能な場合があります。
readonlyはフィールドの“型”ではなく、任意のフィールド型(Char、Integer、Many2one、Dateなど)に付けられる属性です。実行時の振る舞いを制御するためのフレームワーク機能です。
読み取り専用フィールドがどのように動作するか
挙動を理解するためには、ORM(Python側)とビュー(XML側)の双方を押さえると分かりやすくなります。
ORMレベルでのreadonly
ORMでは、モデル定義時にフィールドにreadonly=Trueを付けると常に編集不可になります。これは計算フィールド(compute)でよく使われ、値が別のデータから自動算出される場合に適しています。
この指定はOdooのフィールドAPIの一部で、どのビューを使っても常に有効です。開発者向けドキュメントにも記載があります。
ステート(状態)に応じた読み取り専用化
よくあるパターンは、書類のステータスに応じてフィールドをロックすることです。販売や購買、会計など標準モジュールでは、ドラフトを越えたタイミングで編集を禁止することで履歴を守ります。
Odoo 16まではXMLのattrsで条件を指定していましたが、Odoo 17以降はフィールド要素にインラインの式を置けるようになり記述が簡潔になりました。
どちらの方法でも目的は同じで、ドラフト時のみ編集可能にし、その後はロックするというワークフロー上の基本動作を実現します。
計算フィールドと読み取り専用
computeで定義されたフィールドはデフォルトで読み取り専用になります。値が他のフィールドから導出されるため、ユーザーが直接上書きすることは想定されていません。
値をDBに保持したい場合はcomputeに加えてstore=Trueを指定します。保存済みの計算結果は検索やソートで高速に扱えるため、パフォーマンス改善によく使われます。
計算フィールドを編集可能にする方法
計算フィールドに逆演算(inverse)メソッドを定義すると、ユーザーが値を書き込んだときの処理を実装できます。inverseが無ければフィールドは読み取り専用のままです。これはやや進んだORMの使い方になります。
業務での利用シーン
読み取り専用フィールドはあらゆるモジュールで使われています。実務でよく見かける代表例を紹介します。
1. CRM:成約・失注時のロック
商談中は予想売上やクローズ予定日を更新できますが、成約(Won)や失注(Lost)になった時点でこれらをロックして当時の記録を保持します。
後から数値を変更されると営業報告やパイプライン分析が歪むため、修正履歴を残す仕組みが重要です。
2. 販売:確定受注行の保護
受注が確定したら受注行の商品・数量・価格は編集不可になります。顧客へ確認済みの内容を安定して保つためです。
変更が必要なら一度ドラフトへ戻すなど明示的な手順を踏ませ、意図しない修正を防ぎます。
3. 在庫:出庫・入庫の確定数量の固定
入出庫を検証した後は実際に動かした数量がロックされ、在庫評価の整合性を保ちます。
検証後に数量が勝手に変わると、複数ロケーション間で在庫が不整合になるリスクがあります。
4. 会計:仕訳の仕訳行の固定
仕訳が仕訳帳に計上されると、その行は編集不可になります。多くの法域で会計上の要件となっているほか、簿記の原則に基づく保全措置です。
計上後に自由に修正できると財務諸表の信頼性が損なわれます。
5. 製造:完了した作業指示の実績データ
作業指示が完了すると実績時間や製造数量をロックして、原価計算や生産性分析に使える正確な記録を残します。
読み取り専用フィールドの作り方・カスタマイズ方法
読み取り専用フィールドの設定方法は大きく分けて2通りです。コード不要のOdoo Studioと、Python/XMLでの技術的カスタマイズです。
Odoo Studioを使う場合
Studioを使えばプログラミングなしでreadonlyを切り替えられます。基本手順はシンプルです。
- メインメニューからOdoo Studioを起動します(鉛筆アイコン)
- 設定したいフォームビューへ移動します
- 編集したいフィールドをクリックします
- 右側のプロパティパネルで「読み取り専用」を切り替えます
- 保存してStudioを閉じます
Studioでは条件付きの読み取り専用もドメイン式で設定可能です。たとえば、ステータスが特定値のときだけ読み取り専用にする、といった設定がコード不要でできます。
Studioでの変更はデータベースに保存され、モジュールのアップグレードで上書きされにくいため、簡単で安全にルールを強制したい管理者やコンサルタントに向きます。
技術的にPythonで設定する場合
開発者が独自モジュールを作る際は、Pythonモデルのフィールド定義でreadonly属性を指定します。これはOdooの標準的なフィールド指定方法です。
readonly=Trueを静的に付けると恒久的に編集不可になります。より柔軟にしたいときはstatesパラメータで、どのステータス時に書き込み可能かを定義できます。
既存モデルにカスタムフィールドを追加する場合など、フィールドのロジックをデータモデル側で管理するとビューごとに散らばらず保守性が高くなります。
XMLビューでの設定方法
ビュー単位でreadonlyにするには、ビューXMLのフィールド要素にreadonly属性を付けます。技術カスタマイズで一般的な手順です。
ビューで指定する利点は柔軟性です。同じフィールドが別ビューでは編集可能、別ビューでは読み取り専用、という使い分けが可能になります。標準フィールドに制限を付けたいがPython定義は変更したくない場合に有効です。
Odoo 17ではreadonly条件をインラインで書ける構文が導入され、以前のattrs辞書より読みやすくなっています。バージョンに応じてどちらの書き方も有効です。
実務でのベストプラクティス
読み取り専用を効果的に使うには、適切なレイヤーで、適切な理由に基づいて適用することが大切です。以下は実務での指針です。
1. コンテキストが変わる場合はビュー側で指定する
フィールドが特定のビューやステータスでのみロックされるなら、モデル側ではなくビュー側にreadonlyを置きましょう。これによりバックエンドやAPI連携が必要なときに柔軟に書き込みできるようになります。
2. ドキュメントのライフサイクルに合わせて条件設定する
読み取り専用にするタイミングは、ドキュメントの自然な工程に合致させるべきです。適切な段階でロックすることで、ユーザーにとって直感的で予測可能な操作が実現します。
3. ユーザーロールごとに動作を検証する
読み取り専用はアクセス権と絡むと意図しない結果になることがあります。一般ユーザー/管理者など複数の権限で挙動を必ず確認してください。
4. 必要に応じて必須(required)と組み合わせる
ドラフト時に必須で、確定後に読み取り専用にする、といったパターンはよく使われます。ビューXMLで両方の属性を組み合わせると分かりやすく実装できます。
5. 読み取り専用の理由をコメントで残す
カスタム開発では「なぜこのフィールドをロックするのか」をコードやXMLコメントに書き残しておきましょう。将来の保守担当者がビジネス上の理由を理解しやすくなります。
6. 単純なケースはStudioで、複雑な処理はPythonへ
簡単な条件付けや迅速な変更はStudioで対応し、クロスフィールドの複雑な条件や逆演算が必要な場合はPythonで実装するのが現実的です。
よくある落とし穴
読み取り専用に関しては経験者でも陥りがちな問題があります。代表的なものを把握しておきましょう。
ビューでreadonlyにしただけでセキュリティが担保されたと思い込むこと
ビュー単位のreadonlyはUIの制約に過ぎません。XML-RPCやORMのwrite、サーバーアクションからの更新は防げません。本当に書き込み禁止にしたければORMレベルやアクセス権で制御する必要があります。
恒久的なreadonlyで本来は条件付きにすべき箇所を塞いでしまうこと
保護のつもりで恒久的にロックすると、ドラフトに戻して修正するなど本来想定しているワークフローを阻害してしまうことがあります。ライフサイクル全体を考えてから決めましょう。
onchangeの挙動を見落とすこと
readonlyフィールドがonchange内で参照・設定されていると、画面上で一時的に更新されるように見えたり、エラーになることがあります。onchangeロジックはreadonlyを考慮して実装してください。
全てのビューで一貫してreadonlyを適用していないこと
フォームでは読み取り専用でも、リストやカンバンで同じフィールドが編集可能なままになると混乱を招きます。表示される全てのビューを確認しましょう。
標準モデルを継承してreadonly=Trueを付けたときの副作用
既存フィールドに恒久的なreadonlyを追加すると、標準のビューも含めて全てに影響します。他のカスタマイズとの兼ね合いを確認してから行ってください。
まとめ
読み取り専用フィールドは、業務手順を導き、データの整合性を守り、訓練に頼らずルールを強制するための基本的な道具です。
重要なのはビューレベルとモデルレベルの使い分けを理解し、実際の業務フローに合う条件でロックすることです。適切に配置されたreadonlyは、ドキュメントの各段階で効果を発揮します。
Studioでコードを書かずに設定しても、Python/XMLで細かく制御しても、根底にある考え方は同じです:値を見せつつ、意図しない変更から守ること。
派手な機能ではありませんが、使い方次第でOdoo運用の安定性に大きく寄与します。
Dasoloでは、業種を問わずOdooの導入・カスタマイズ・最適化を支援しています。フィールド設計やワークフロー構築、データモデル改善の相談を受け付けています。 お問い合わせはこちらから あなたのプロジェクトについてお聞かせください。