コンテンツへスキップ

Odoo の Binary Field 完全ガイド:使い方と実践例

OdooのデータモデルにおけるBinaryフィールドを実務視点で解説します。ファイルやドキュメントの保存方法、添付ファイルの管理、開発時に必要となるカスタマイズや技術的注意点まで、現場で役立つノウハウをわかりやすくまとめました。
2026年3月6日 by
Odoo の Binary Field 完全ガイド:使い方と実践例
Dasolo
| まだコメントがありません

はじめに


地味だが重要——実運用のOdooではバイナリフィールドが至るところで働いています。ユーザーが契約書をアップロードしたり、製品の仕様書を添付したり、会社ロゴをレコードに保存したりするとき、背後には必ずバイナリ型のフィールドが存在します。どこにデータが保存されるのか、実際のファイル管理はどう仕組まれているのか、そしていつ別の型を選ぶべきかを理解することで、カスタムフォーム設計やモデル拡張の品質が大きく変わります。


本ガイドでは、バイナリフィールドが何を保持するか、attachmentモードが保存方式とパフォーマンスに与える影響、Odoo StudioやPythonでの作成方法、およびCRM・人事・在庫などの実務的な活用例を解説します。

Odooにおけるバイナリ(ファイル)フィールドとは?


OdooのORMでは、バイナリフィールド(fields.Binary)はファイルやドキュメント、画像などの生データを扱います。画面上ではファイルをアップロードするボタンとして表示され、アップロード後は同じ場所からワンクリックでダウンロードできます。


最も重要なのは“どこに保存されるか”です。近年のOdooはデフォルトでattachmentモードを採用しており、実際のファイルはir.attachmentテーブルとサーバのfilestoreに置かれ、モデルのカラムには添付レコードを指す参照(ID)だけが格納されます。これにより主要テーブルが膨らまず、ファイル管理をOdooの仕組みに任せられます。


Odoo Studioのフィールド選択ではバイナリは「File」と表示され、フォーム上ではシンプルなアップロード/ダウンロード操作で扱えます。画像専用にはfields.Imageという派生型があり、自動リサイズやサムネイル表示を行うため、画像用途はそちらを使うのが適切です(後述)。


Pythonモデルでの定義イメージ


from odoo import fields, models

class ResPartner(models.Model):
    _inherit = 'res.partner'

    x_signed_contract = fields.Binary(
        string='Signed Contract',
        attachment=True,
    )
    x_signed_contract_filename = fields.Char(
        string='Signed Contract Filename',
    )

ここで注目したいのがx_signed_contract_filenameのようなファイル名用の補助Charフィールドです。アップロードした元のファイル名を保存しておくことで、ユーザーがダウンロードしたときに意味のある名前で保存されます。これを省くとダウンロード時に一般的な名前になってしまうため、実務ではセットで用意するのが標準的です。

フィールドの仕組みについて


モデルにバイナリフィールドを追加すると、モジュールのインストールやアップグレード時にOdooが必要なカラムを自動で作成します。開発者側で手動のSQLを用意する必要はありません。


保存モードについて

バイナリフィールドのattachmentパラメータはファイルの実際の格納先を制御します。


  • attachment=True(推奨):ファイル実体はir.attachmentに保存され、レコードはモデル名とIDで紐付けられます。モデルのカラムには参照情報のみが残るため、テーブルが軽く保たれ、Odooのfilestoreによる効率的なファイル管理が利用できます。
  • attachment=False:base64化されたデータが直接モデルのカラムに入ります。テーブルサイズが急増し、クエリ全体の遅延を招くため、サムネイル程度以外では避けるべき設定です。

データ形式について

バイナリフィールドはbase64エンコード済みの文字列で入出力されます。ORMやXML-RPCで読み書きする際はbase64文字列を受け取り、書き込む場合も同様の形式が必要です。


実務では、書き込む前にエンコードし、読み出し後にデコードするワークフローを守ります。


import base64

# Writing a file to a Binary field
with open('document.pdf', 'rb') as f:
    encoded = base64.b64encode(f.read()).decode('utf-8')
record.write({'x_signed_contract': encoded})

# Reading a file from a Binary field
raw_bytes = base64.b64decode(record.x_signed_contract)

設定可能な主な属性

バイナリフィールドでよく使う主要属性をまとめます。


  • attachment: Boolean。ir.attachmentに保存するか(True)カラムに直接保存するか(False)を制御します。近年のデフォルトはTrueです。
  • string: 画面に表示するラベル。
  • required: レコード保存時に必須にするかどうか。
  • compute: Pythonメソッドで動的に生成する場合に使います。たとえばPDFをオンザフライで生成する用途などです。
  • store: computeと組み合わせて計算結果をDBに保存するかを制御します。
  • groups: 特定ユーザーグループだけに表示・編集を許す制限。機密文書の扱いで重要です。
  • copy: レコード複製時に値をコピーするかを制御。attachmentモードやOdooバージョンで既定値が変わります。

fields.Imageについて

fields.Imageはfields.Binaryの派生で、Odoo 13以降に導入されました。自動リサイズやプレビュー用サムネイルを生成し、フォームで画像プレビューを表示します。製品画像や社員写真、ロゴのような視覚コンテンツにはfields.Imageを使うと、不要に大きなアップロードを防ぎUXも向上します。


ビューでの見え方

フォーム上のバイナリは基本的にアップロード/ダウンロード用のコントロールとして表示されます。画像ならwidgetにimageを指定してサムネイル表示にすると便利です。一覧ビューでは全行のファイル本体を読み込むと通信コストが高くなるため、直接表示せずに添付の有無を示すアイコンやブール値を出すのが一般的です。

実務での活用例


以下では、業務でよく使われる具体例をいくつか紹介します。


CRM:顧客レコードに署名済みのNDAや契約書を格納

営業活動の中で、取引先やリードに紐づく署名済み文書を直接保存しておくと便利です。res.partnerやcrm.leadにバイナリを追加すれば、営業担当は画面上でワンクリックで契約書を参照できます。簡易的なドキュメント管理として十分機能し、別途システムを用意する手間を省けます。


人事(HR):従業員関連書類の保管

身分証明書、就業契約書、就労許可証、研修証明書など、HRが扱う個人情報はhr.employeeにバイナリで添付しておくのが一般的です。groups属性で閲覧権限を制限することで、HRマネージャーのみがファイルを確認できるようにし、プライバシーやコンプライアンス要件に対応します。


在庫(Inventory):製品仕様書や安全データシートの添付

技術資料やSDS(安全データシート)、品質証明書などをproduct.templateに保持すると、購買や倉庫担当が必要な情報にすぐアクセスできます。製造業や卸売業でよく依頼されるカスタマイズで、Odoo Studioやモジュールで簡単に追加できます。


営業(Sales):捺印や署名画像の管理

見積書や注文書に会社印や代表者の署名を自動で挿入したいケースがあります。res.companyにfields.Imageでロゴや印影を保持しておけば、QWebテンプレートから参照して印刷物に反映できます。大量の見積発送がある環境で手作業を減らし、未署名送信のミスを防げます。


会計(Accounting):経費明細に領収書を添付

経費精算では領収書のスキャンを添付することが必須のワークフローです。標準の経費機能なら添付機能が備わっていますが、カスタムモデルや外部連携を使う場合はバイナリフィールドを直接用いてレコードに保持し、承認フローに組み込むのが実用的です。

バイナリフィールドの作成方法とカスタマイズ


バイナリフィールドを追加する方法は主に3つ。技術レベルや運用要件に応じて選びます。


Odoo Studio(ノーコード)で追加する方法

Odoo Studioはローコードのカスタマイズツールで、開発知識が無くてもフィールド追加が可能です。手順は次の通り。

  1. メインメニューからOdoo Studioを起動。
  2. フィールドを追加したいフォームを開く。
  3. フィールドピッカーからFileをドラッグしてフォームに配置。
  4. プロパティパネルでラベルや表示条件を設定。
  5. 保存してStudioを閉じる。

Studioはx_studio_プレフィックス付きでフィールドを作成し、attachmentモードを自動で使います。DB側の設定は不要で、ビジネスユーザーが短時間でファイルアップロード機能を追加できる有用な手段です。


カスタムモジュール(Python)で定義する方法

複数環境で管理したりバージョン管理が必要な場合は、Pythonでモデルにフィールドを定義するのが標準的で推奨される手法です。


from odoo import fields, models

class HrEmployee(models.Model):
    _inherit = 'hr.employee'

    x_id_document = fields.Binary(
        string='ID Document',
        attachment=True,
        groups='hr.group_hr_user',
    )
    x_id_document_filename = fields.Char(
        string='ID Document Filename',
    )

フィールド定義後はフォームビューにbinaryウィジェットを追加し、filename属性で補助のCharフィールドを指すようにします。モジュールのインストール/アップグレード時にOdooがDBカラムを自動生成するため、Odoo.shやオンプレ環境でも動作します。


XML-RPC APIで作成する方法

リモートの構成スクリプトやデプロイ用ノートブックから自動的にフィールドを作る場合にはXML-RPC経由で定義できます。


field_id = models.execute_kw(
    ODOO_DB, uid, ODOO_API_KEY,
    'ir.model.fields', 'create',
    [{
        'name': 'x_custom_document',
        'field_description': 'Custom Document',
        'model_id': model_id,
        'ttype': 'binary',
        'state': 'manual',
    }]
)

stateにmanualを指定すると、そのフィールドがモジュール由来ではなく手動作成であることを示します。現行バージョンではAPI経由で作られたフィールドもデフォルトでattachmentモードになります。自動設定スクリプトやリモートデプロイに向く手法です。

運用上のベストプラクティス


1. 常にattachment=Trueを使うこと

特別な理由がない限り、ファイル実体をDBカラムに格納するのは避けてattachmentモードを使ってください。テーブル肥大化やクエリ遅延のリスクが高く、大きなファイルを扱う場合は事実上必須の設定です。近年のOdooではデフォルトがTrueなので、明示的に指定しなくてもOKな場合が多いですが、運用方針として徹底しましょう。


2. ファイル名用のCharフィールドをセットで用意すること

アップロードされた元のファイル名を保持するフィールド(_filename系)は必須級のUX改善です。無いとダウンロード時にgenericな名前になりユーザーの混乱を招きます。コード一行で済む小さな投資が利用感を大きく向上させます。


3. 画像はfields.Imageを使うこと

製品画像や社員写真、ロゴなど視覚データにはfields.Imageを選びましょう。自動でサイズ制限やサムネイル生成が働き、不要な大容量ファイルの保存を防げます。型を用途に合わせることは健全なデータ設計の基本です。


4. groupsでアクセス制御を設けること

従業員文書や契約書、財務関連ファイルなど機密性の高いデータはgroups属性で読み書きを制限してください。プライバシー保護や監査要件の遵守に直結する重要な設定です。


5. コード中でのbase64処理を厳密に扱うこと

プログラムで読み書きする際は必ずエンコード・デコードを明示的に行ってください。書き込み前はbase64.b64encode(file_bytes).decode('utf-8')、読み出し後はbase64.b64decode(field_value)を使うのが安全です。形式の想定違いは実運用で頻繁にバグを生みます。

よくある落とし穴


attachment=Falseを選ぶリスク

ファイルをDBカラムに直接入れるとPostgreSQLテーブルが急速に肥大化します。数十件のPDFでも数百MB単位で膨らみ、そのモデルの全クエリが遅くなるため非常に大きな問題です。一度こうしてしまうとattachmentモードへ移行するのは手間のかかるマイグレーション作業になります。


ファイル名フィールドを忘れること

補助のファイル名フィールドが無いと、ユーザーがファイルをダウンロードした際に意味のない名前になりがちです。ユーザー体験を整えるために必ず追加しておきましょう。


BinaryとImageを混同すること

画像に対して単純なBinaryを使うと自動リサイズやサムネイルが働かず、極端に大きな画像が保存されてフォーム表示が重くなります。逆にPDFなど非画像にImage型を使うと処理エラーが起きます。用途に合った型を選んでください。


一覧ビューに直接バイナリを含めること

リストビューにバイナリをそのまま表示すると、表示される各行のファイル本体を読み込むため大容量のデータ転送が発生します。多数レコードを扱う一覧では、添付の有無を示すブールやアイコンで代替するのが正しい設計です。


処理時にFalseチェックを忘れること

値がないバイナリはPythonではFalseが返ります。空文字や空バイトではありません。チェックなしでbase64デコードしようとするとTypeErrorで処理が落ちるため、常にif record.x_document: のように存在チェックしてから処理してください。

まとめ


バイナリフィールドは単純だが重要な要素です。ファイルやドキュメントをOdooの画面・添付システム・アクセス制御の下で自然に扱えるようにする役割を果たします。


身につけるべき習慣は明快です:attachmentモードを使う、ファイル名用のCharフィールドを添える、画像はfields.Imageで扱う、機密ファイルにはgroupsで制御する、そしてコードではbase64処理を慎重に行う。これらを守れば運用上のトラブルの多くは未然に防げます。

Odoo Studioでのフィールド追加、カスタムモジュールの実装、あるいはORMやXML-RPC経由での自動作成いずれの場合でも、バイナリの扱いを初期段階で正しく設計することで、より堅牢で管理しやすいOdoo環境が得られます。

Dasoloについて お気軽にご相談ください 貴社のOdoo導入・カスタマイズ・最適化を支援します。データモデル設計からファイル管理ワークフローの構築、モジュール開発まで、当社チームがサポートいたします。

Odoo の Binary Field 完全ガイド:使い方と実践例
Dasolo 2026年3月6日
このポストを共有
サインイン コメントを残す