多言語をまたいで業務をする会社では、同じデータを言語ごとに見せ分ける仕組みが不可欠です。たとえばフランス語の営業担当、ドイツ語の倉庫担当、スペイン語を使う顧客——それぞれに自分の言語で表示されることを期待されます。Odooの「翻訳可能フィールド」は、そうした表示のために単一レコードの中で言語別の値を保持する機能です。
翻訳可能フィールドは、言語ごとに別々の値を保持します。たとえば同じ製品レコードでも、フランス語ユーザーにはフランス語の製品名が、ドイツ語ユーザーにはドイツ語の製品名が表示されます。データは1件でも、表示は利用者の言語に合わせて変わる──これが基本概念です。
この記事では、OdooのORMにおける翻訳可能フィールドの仕組み、作成方法、運用時に効果を発揮する具体的なユースケースを解説します。多言語対応を設計する際の指針としてお読みください。
Odooにおける「翻訳可能フィールド」とは何か
翻訳可能フィールドとは、Odooデータモデル上のテキスト系フィールドで、システムで有効になっている各言語ごとに別個の値を格納できるものです。ユーザーは特別な操作なしに自分の言語で値を参照でき、表示は透過的に切り替わります。
どのフィールドタイプが翻訳に対応するかというと:
- Char(短い一行テキスト)例:製品名、カテゴリ名、役職など
- Text(複数行の長文)例:製品説明、備考、内部メモなど
- Html(HTMLを含むリッチテキスト)例:ウェブページ本文、メールテンプレートの本文など
数値、日付、Many2one、ブールなどの非テキスト系フィールドは翻訳対象ではありません。翻訳は「人が読むテキスト」に限られます。
UI上の見え方
編集モードでは、翻訳可能なフィールドの横に小さな「国旗アイコン」や言語アイコンが表示されます。これをクリックすると各言語の値を一括で編集できるダイアログが開き、権限のあるユーザーが一箇所で翻訳を管理できます。
読み取りモードでは、ユーザーは単に自分の言語での値を見るだけです。もしその言語の翻訳が未登録なら、空欄にするのではなくデータベースの基準言語(通常は英語)を代わりに表示するため、表示が欠けることは基本的にありません。
翻訳可能フィールドの仕組み
内部構造を知っておくと、いつ翻訳可能フィールドを使うべきか、スケールする際にどう管理するかの判断がしやすくなります。
translate=True パラメータについて
ORM上では、フィールド定義に translate=True を付けるだけで翻訳可能になります。開発者がカスタムで短いテキストを作る際に使う典型的な手法です。
(Pythonでの定義例をここに置く代わりに)モデルのフィールドに translate=True を設定すると、そのフィールドは言語別に値を保持するようORMが扱います。
この1つのフラグだけで、Odooは言語コンテキストに応じた読み書きを自動的に行います。フレームワーク上でもっともシンプルかつ便利な機能の一つです。
翻訳データの保存場所
保存方法はOdooのバージョンで変わりました。
- Odoo 15以前:翻訳値は ir.translation という専用テーブルに行ごとに格納され、モデル名やフィールド名、レコードID、言語コードで紐付けられていました。
- Odoo 16以降:翻訳は各モデルのテーブル内に JSONB カラムとして保持されるようになりました。たとえば name フィールドなら {"en_US": "Laptop Stand", "fr_FR": "Support..."} のようなJSONで1カラムにまとめられます。
JSONBへの移行はパフォーマンス上の利点が大きく、特にレコード数が多いモデルでの検索や取得が速くなり、以前のような高コストな結合処理を避けられるようになりました。
言語コンテキストの仕組み
Odooが翻訳可能フィールドを読むときは、コンテキスト内の「アクティブ言語」を参照します。フランス語でログインしていればORMは自動的にfr_FRの値を返します。API経由の呼び出しでは、コンテキストで言語を明示して制御できます。
(API呼び出し例の代わりに)APIで読み書きする際は、contextに 'lang': 'fr_FR' のような言語指定を渡すことで、どの言語の値を取得・更新するかを明確にできます。
外部システム連携やデータエクスポートを作るときは、必ず適切な言語コンテキストを渡すことが正しい値を扱う鍵です。
translate にコール可能オブジェクトを渡すケース
translate パラメータは callable(関数)も受け付けます。たとえば translate=_ としてモジュール内の選択肢ラベルなど静的文字列を翻訳対象としてマークし、Odooの翻訳エクスポートで扱えるようにする用途があります。これはレコード単位の翻訳とは別の扱いで、モジュール文字列の国際化に使います。
フォールバック(代替表示)の挙動
アクティブ言語に翻訳が存在しない場合、Odooは空文字を返すのではなくデータベースの基準言語にフォールバックします。これにより部分的にしか翻訳が整っていない環境でも利用者に意味のある表示を提供できます。
実務での活用例
翻訳可能フィールドは単なる技術機能ではなく、多言語で事業を行う際の実務課題を解決します。以下に代表的な5つの利用シーンを挙げます。
1. Eコマース:多言語の製品名・説明
自社のオンラインショップで販売する場合、顧客は自分の言語で商品情報を見たいものです。product.template の name や description が翻訳対応なら、同じカタログで言語ごとのローカライズを行え、レコードの重複や在庫・価格の分断を避けられます。
たとえばフランス語サイトの訪問者はフランス語の名称・説明を見ますが、在庫や価格は共通のままです。表示テキストだけをローカライズするイメージです。
2. 多国籍向けのメールテンプレート
メールテンプレート本体はHtmlフィールドで翻訳可能です。注文確認メールをドイツの顧客に送る際、ドイツ語版のテンプレート本文が設定されていれば自動でそちらが使われます。
これにより、言語ごとにテンプレートを複数作る必要がなく、単一テンプレートで各市場に対応できます。
3. ウェブサイトやブログの多言語対応
OdooのウェブページはHtmlの翻訳機能を使って各言語ごとの本文を管理できます。複数言語を有効にすれば、同じページの言語別バージョンを編集者が個別に保守できます。追加プラグインを使わずにネイティブに多言語サイトを構築できます。
SEOの観点でも、言語ごとにmeta titleやmeta descriptionを用意できるため、各市場の検索結果での露出を高めることが可能です。
4. 選択肢ラベル(Selection)を国際対応する場面
Selectionフィールドの選択肢ラベルは開発時に _ 関数でマークすれば翻訳可能です。たとえば「進行中/保留/完了」のようなステータスは各言語のユーザーに適切に表示できます。
これはHRやプロジェクト管理など、複数拠点で同じワークフローを扱う場合に特に役立ちます。
5. 多言語レポート向けのカスタムフィールド
Studioやカスタム開発で追加した内部分類用フィールド(サービス区分、リスクレベル、製品セグメント等)も翻訳可能にしておくと、ダッシュボードやレポートが利用者ごとに正しく表示され、混乱を避けられます。
もし翻訳を設定していないと、フランス語ユーザーがレポートで英語ラベルを目にするなどの齟齬が生じ、現場の採用率低下につながります。
翻訳可能フィールドの作成・有効化方法
翻訳可能フィールドを作る方法は、コード(Python)で定義する方法と、ノーコード/Studioで作った後に有効化する方法があります。
Pythonでの定義(開発者向け、推奨)
最もクリーンなのはPythonモデルでフィールドに translate=True を付ける方法です。これは全ての開発ガイドが推す標準的な手法です。
(Pythonコード例の代わりに)CharやHtmlフィールドに translate=True を追加すると、そのフィールドは即座に翻訳対応になります。
translate=True を付けるだけで、UIの言語アイコン、保存形式、フォールバック動作といった一連の仕組みをOdooが自動で取り扱います。
Odoo Studioで作成したフィールドを翻訳可能にする方法
Studioのフィールド作成画面には translate オプションが出ないため、Studioで作ったCharやTextは作成直後は翻訳不可です。
ただし、XML-RPCや外部スクリプトで ir.model.fields を更新し、対象フィールドの translate プロパティを True に変更すれば翻訳を有効化できます。
(API操作の手順は省略)外部スクリプトでフィールドを検索し、translate を true に更新するワークフローで対応できます。
この方法は、ソースコードにアクセスできない管理者やコンサルタントがカスタマイズを行う場面で有用です。
翻訳の管理:エクスポートとインポートの流れ
翻訳対象が増えたら、Odooの翻訳エクスポート/インポート機能を使うのが実務的です。大規模作業はこのワークフローが効率的です。
- Settings > Translations > Export Translation から .po や .csv を出力し、未翻訳の文字列や既存の翻訳をまとめて取得します。
- ファイル内で翻訳を埋めるか、翻訳者に渡して作業してもらいます。
- 翻訳が埋まったら Settings > Translations > Import Translation でアップロードして反映します。
レコード単位の翻訳(製品名のようなもの)はUIの言語アイコンで直接編集することもでき、小規模な修正にはこちらが便利です。
API経由での翻訳登録
XML-RPCなどAPIで翻訳値を書き込む場合は、contextに言語を指定して書き込みます。
(API例の代わりに説明)たとえばフランス語の訳を登録する際は context に 'lang': 'fr_FR' を付けて write を行えば、その言語だけが更新されます。
特定言語を明示して書き込むと、その言語の値だけを変更し、他言語の値を壊さないので外部連携では推奨される方法です。
運用のベストプラクティス
正しく使えば翻訳可能フィールドは扱いやすいですが、運用上いくつかの注意習慣を持つとトラブルを避けられます。
まずは基準言語の値をしっかり整えること
他言語の翻訳を作り始める前に、基準言語(ベース言語)の文言を完成させておきましょう。基準文を後で変更しても翻訳は自動で追従しないため、同期が崩れる原因になります。
本当に必要なフィールドだけを翻訳対象にする
全てのテキストを無差別に翻訳可能にすると管理負担が増えます。内部参照コードや社内専用の技術フィールドなど、多言語化の恩恵が少ないものは翻訳対象から外す判断も重要です。
大量の翻訳作業はエクスポート/インポートを使う
製品数が数百〜数千になる場合、UIで1件ずつ編集するのは非現実的です。エクスポートして一括編集、インポートで反映するフローが効率的でミスも少なくなります。
API呼び出しでは言語コンテキストを常に指定する
APIで読み書きする際は常に context に 'lang': 'xx_XX' を含めましょう。指定しないとユーザーのデフォルト言語が使われ、意図しない言語にデータが書かれてしまうリスクがあります。
基準文を変更したら翻訳のメンテを忘れない
ベース言語の文言を更新した際は翻訳者に通知する仕組みを作り、翻訳の見直しを行うプロセスを運用に組み込みましょう。自動更新はされません。
よくある落とし穴
経験あるコンサルタントでもこれらの落とし穴に遭遇します。事前の配慮が後のデバッグ時間を節約します。
API書き込みで言語コンテキストを渡し忘れる
外部連携時によくあるミスです。言語指定なしで製品名を書き込むと、現在のユーザーの言語(たとえば英語)で上書きされ、本来更新したかった他言語の訳が壊れてしまうことがあります。言語は明示してください。
検索時の翻訳の扱いを誤解する
翻訳フィールドで検索するとき、Odooはアクティブ言語で検索します。英語でしか値が入っていない「Laptop Stand」は、フランス語ユーザーが検索してもフランス語の翻訳が未設定ならヒットしません。検索前に翻訳があるか確認しましょう。
翻訳・非翻訳フィールドを混在させたレポート作成の落とし穴
レポートで翻訳対応の有無が混在すると、あるラベルは利用者の言語で、別のラベルはベース言語のままといった不整合が生じます。レポート作成時に各フィールドの翻訳要否を事前に判断してください。
計算フィールドと翻訳のオーバーヘッドを考慮しない
複数の翻訳フィールドを結合して算出するcomputedフィールドは、リクエスト時のアクティブ言語で計算されます。言語別に保持したい結果がある場合は、言語ごとに計算・保存するロジックを設計する必要があります。
言語を削除して翻訳データを放置する
言語を無効化・削除しても、その言語用の翻訳データがDBに残るケースがあります(バージョン依存)。無害であることが多いものの、データが増えるため、本番で言語を外したら翻訳データの状況を確認しておくことを勧めます。
まとめ
翻訳可能フィールドは、多言語の企業にとって実務面で非常に有用な機能です。たったひとつのフラグ(translate=True)で、製品カタログ、メールテンプレート、ウェブページ、カスタムフィールドなどを言語ごとに管理でき、レコードの重複や別システム管理の手間を減らせます。
重要なのは、どのフィールドを翻訳するかを意図的に選ぶことです。ユーザー体験や顧客向け表示に差が出る箇所だけを翻訳対象にし、規模が大きければエクスポート/インポートで運用し、API利用時には常に言語を明示してください。
多言語ECの立ち上げ、海外拠点へのOdoo展開、あるいはカスタムモジュール開発──いずれの場合も翻訳可能フィールドを正しく扱えれば、より使いやすく整った仕組みが作れます。
多言語対応のOdoo導入でフィールド設定や翻訳ワークフローの支援が必要ですか? Dasoloチームにご相談ください。 私たちが最適な設定と運用の設計をお手伝いします。