MY HATCH

アップデートしても壊れない — Odoo の拡張の作り方

公式の Odoo には手を入れず、アドオンで足す。そのうえで「やってはいけない 8 つ」を守る。Odoo 19 で実験して確かめた、版上げに耐える拡張の作り方を説明します。

8分
最終更新: 2026年10月26日
Odoo Communityアドオンカスタマイズ版上げ
目次

目次

このページには目次がありません

アップデートしても壊れない — Odoo の拡張の作り方

業務システムに手を入れるとき、いちばん心配なのは「直したところが、次の版上げで動かなくなる」ことです。Odoo では、公式の Odoo には手を入れず、アドオンという別の部品として足すのが基本です。ただし Odoo の拡張の道具はとても強く、使い方を誤ると、エラーも出ずに他の部品の処理が消えます。

この記事では、当社が Odoo 19.0-20261015(Community)で行った 11 の実験・28 項目の結果をもとに、版上げに耐える作り方と、やってはいけないことをまとめます。

3 つの層に分けて置く

当社は、足す物を 3 つの層に分けて置きます。

3 つの層:御社ごとの部品・日本向けの部品・公式の Odoo

層置く物版を上げるとき
御社ごとの部品御社だけの項目・帳票・手順新しい版へ移し、御社の業務で動くか確かめる
日本向けの部品締め請求・入金の消込・承認・日本の様式の帳票など、日本の会社に共通の物当社が新しい版へ移す
公式の Odoo(Community)公式が配布する本体中身は書き換えず、新しい版に入れ替える

判断はシンプルです。どの会社にも害の無い物は「日本向け」へ、御社だけの物は「御社ごと」へ。御社の部品で公式の動きを止めたり、見える範囲を広げたりしたくなったときは、先に日本向けの部品に「切り替えのスイッチ」を用意し、御社の側ではそれを入れるだけにします。

Odoo の足し方

Odoo は、公式の部品を書き換えずに足すための道具を、最初から持っています。

  • モデルの継承:_inherit で、公式のモデル(例:受注)に項目や処理を足す
  • 画面の継承:公式の画面を指して、「この項目の後ろに足す」と書く
  • 処理の上書き:公式の処理を上書きし、その中で super() を呼んで元の処理も動かす
  • データの初期値:XML で配り、現場で変える値には noupdate="1" を付ける
  • 版ごとの移し替え:アドオンの版を上げ、その版のフォルダに移し替えの手順(upgrade script)を置く

たとえば「受注を確定したら、御社のルールで 1 つ処理を足す」なら、次のように書きます。

from odoo import models

class SaleOrder(models.Model):
    _inherit = "sale.order"

    def action_confirm(self):
        res = super().action_confirm()   # 公式の確定と、他のアドオンの処理を先に動かす
        for order in self:
            order._jp_after_confirm()     # 足したい処理は、別のメソッドに切り出す
        return res

公式の受注の画面にも、公式のアドオンどうしが同じやり方で足し合っています。開発者モードでビューを開くと、継承している画面が並びます。

見積・受注の画面のビュー。継承ビューのタブに、公式のアドオンが足している画面が並ぶ

見積・受注の標準の画面に、CRM・購買・在庫・経費・製造の各アドオンが、継承で 6 つの画面を足しています。上の帯は Odoo 自身の注意書きで、元の画面を直接編集しないよう勧めています。帯の中の Studio は Enterprise の機能です(画面は見本のデータです)

測ってわかったこと:Odoo は「できてしまう」

実験の一番の結論は、Odoo では、公式の処理を取り除くことも、見える範囲を広げることも、アドオンからできてしまうことでした。できる範囲が広いぶん、決まりは「できない」ではなく「やってはいけない」として持つ必要があります。

いくつかの結果を挙げます。

  • super() を呼ばずに上書きした:先に入っていた 2 つのアドオンの処理が、エラーも出ずに消えました。後から super() を呼ぶアドオンを足しても、消えた処理は戻りませんでした
  • 他のアドオンと同じモデル名を、継承なしで定義した:インストールはそのまま通り、元のモデルの項目が見えなくなりました(データベースの列は残ります)
  • 画面の項目を replace で消し、別のアドオンがその項目の後ろに足した:入れる順番によっては、後のアドオンのインストールが止まりました
  • アクセス権を 1 行足した:管理者だけが読めるはずのデータを、一般の利用者が読めるようになりました
  • アドオンで足した項目:そのアドオンを外すと、項目のデータも消えました

やってはいけない 8 つ

上の結果から、当社は次の決まりで作ります。

#やってはいけないこと代わりにすること実験で起きたこと
1他のモジュールと同じモデル名を、_inherit なしで定義する必ず _inherit で足す元の項目が黙って消えた
2super() を呼ばずに上書きする止めたい処理は、日本向けの部品の設定スイッチで止める他のアドオンの処理が黙って消えた
3他のモジュールの画面やデータを、外部 ID で直接書き換える画面は継承で、値は upgrade script で変えるアドオンを外しても元に戻らなかった
4画面の継承で position="replace" を使う属性の変更・後ろに足す・中に足す入れる順番でインストールが止まった
5アクセス権の行や、グループ付きの見える範囲のルールを、軽く足す「緩める変更」として別の人が必ず確かめる。sudo() は使った箇所を数えて残す1 行で一般の利用者が読めるようになった
6外す前の備えなしにアドオンを外す外す前に必ずバックアップ。残したい項目は日本向けの部品に持つ外すと項目のデータが消えた
7業務の処理を、モデルの外の関数に置くモデルのメソッドに細かく切る(そこが後から足せる場所になる)モデルの外の関数は、他のアドオンから差し替えられなかった
8同じ処理を重ねるアドオンどうしの順番を、成り行きに任せるdepends で順番をはっきり書く依存の書き方で、処理の順番が変わった

ほかに、版ごとの移し替えの手順は「アドオンの版を上げ忘れると走らない」「一度走った手順を別の版のフォルダへ移すと、もう一度走って二重になる」ことも確かめました。現場で変える初期値に noupdate="1" を付けないと、アドオンを更新するたびに元の値へ戻ります。

毎年の版上げには、移す作業が要る

ここまでの作り方で、同じ版の中の更新(公式の修正の取り込み)は、公式の Odoo を入れ替え、アドオンを更新してテストを回す、という手順で進められます。

一方、Odoo の大きな版は毎年のように出ます。大きな版をまたぐと、公式の画面の作りや項目の名前が変わることがあり、アドオンを新しい版へ移す作業が要ります。公式に手を入れていないので、移す範囲は「足した部品」に限られます。それでも、作業そのものは無くなりません。

当社は、日本向けの部品を新しい版へ移し、御社ごとの部品も移したうえで、御社の業務の流れで動くかを確かめてから切り替えます。

まとめ

  • 公式の Odoo には手を入れず、日本向けの部品と御社ごとの部品を、アドオンとして足す
  • Odoo の道具は強く、取り除く・緩めることもできてしまう。だから「やってはいけない 8 つ」を決まりとして守る
  • 同じ版の中の更新は入れ替えとテストで進められる。大きな版をまたぐときは、足した部品を移す作業が要る

足した部品は御社の手元に残り、版を上げても使い続けられます。アドオンの作り方そのものは「本格拡張はアドオンで — Odoo の拡張開発の基本」で説明しています。

「作り方」の記事をもっと見る

ERP を、借りずに所有する。

Odoo Community を日本の業務に合わせ、ソース一式を人数無制限でお渡しします。

相談する(無料)