Odoo 自定义模块开发
何时使用
适用于 Odoo(社区版/企业版,v14+)的自定义模块开发场景:
- 从零搭建一个新的自定义模块(脚手架 + manifest + 模型)。
- 扩展既有 Odoo 模型,例如给
sale.order加字段、改行为(用_inherit,绝不改核心文件)。 - 排查模块加载失败、
__manifest__.py配置错误、访问权限报错。 - 正确实现
compute/onchange/@api.constrains等 ORM 方法。
不该用边界:
- 不覆盖 OWL JavaScript 组件与前端 widget 开发;纯 XML 视图构建另用
odoo-xml-views-builder。 - 不覆盖 Odoo 13 及更早结构(无
__manifest__.py自动加载机制)——本技能面向 v14+。 - 不覆盖多公司(multi-company)/多网站(multi-website)配置,那需额外的
company_id/website_id字段。 - 不生成自动化测试文件,那交给
odoo-automated-tests。
步骤
- 确认输入:目标 Odoo 版本、模块名(snake_case)、要建/扩展的模型、依赖应用(如
base、mail、sale)。 - 建目录脚手架:按标准结构创建文件夹与空
__init__.py(见示例)。 - 写
__manifest__.py:填name/version/depends/data,并补author、website便于在 Apps 列表识别。version必须是{odoo版本}.{major}.{minor}.{patch},如17.0.1.0.0。 - 定义模型:在
models/*.py用带命名空间的_name(如hospital.patient),必要时_inherit = ['mail.thread', 'mail.activity.mixin']自动获得 chatter/日志。 - 挂载
__init__.py:在models/__init__.py里from . import xxx,根__init__.py里from . import models,否则模型不会被加载。 - 配安全:每个新模型都要在
security/ir.model.access.csv里给出访问规则,否则用户报权限错误。 - 登记 data:把 view XML、security CSV 等按加载顺序写进 manifest 的
data列表(security 在前)。 - 安装并校验:用 CLI 安装并查看日志确认无加载错误。
指令
扩展 vs 新建的判断:
- 要加字段/改逻辑到现成模型 → 新建模块,模型里
_inherit = '现有模型名'(不写_name),切忌直接编辑核心模块源码。 - 要全新业务对象 → 模型里写
_name = 'your.model'+_description。
CLI 安装与升级(-i 安装,-u 升级已装模块):
# 首次安装模块(--stop-after-init 装完即退)
./odoo-bin -d mydb --stop-after-init -i hospital_management
# 改了 Python/视图后升级模块
./odoo-bin -d mydb --stop-after-init -u hospital_management
示例
目录结构(snake_case,禁用空格/大写):
hospital_management/
├── __manifest__.py
├── __init__.py
├── models/
│ ├── __init__.py
│ └── hospital_patient.py
├── views/
│ └── hospital_patient_views.xml
├── security/
│ ├── ir.model.access.csv
│ └── security.xml
└── data/
__manifest__.py:
{
'name': 'Hospital Management',
'version': '17.0.1.0.0',
'category': 'Healthcare',
'depends': ['base', 'mail'],
'data': [
'security/ir.model.access.csv',
'views/hospital_patient_views.xml',
],
'installable': True,
'license': 'LGPL-3',
}
models/hospital_patient.py:
from odoo import models, fields, api
class HospitalPatient(models.Model):
_name = 'hospital.patient'
_description = 'Hospital Patient'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='Patient Name', required=True, tracking=True)
birth_date = fields.Date(string='Birth Date')
doctor_id = fields.Many2one('res.users', string='Assigned Doctor')
state = fields.Selection([
('draft', 'New'),
('confirmed', 'Confirmed'),
('done', 'Done'),
], default='draft', tracking=True)
扩展既有模型(给 sale.order 加字段):
from odoo import models, fields
class SaleOrder(models.Model):
_inherit = 'sale.order' # 只写 _inherit,不写 _name
delivery_note = fields.Char(string='Delivery Note')
注意事项
- ✅ 模型
_name必须带命名空间前缀(如hospital.patient),避免与核心模型冲突。 - ✅ 用
_inherit = ['mail.thread']一键获得 chatter / 操作日志。 - ✅ manifest 里设
author和website,模块在 Apps 列表才可识别。 - ❌ 绝不直接修改 Odoo 核心模型源码——一律用
_inherit,否则升级即被覆盖。 - ❌ 新模型忘记写进
ir.model.access.csv→ 用户访问报错。 - ❌ 文件夹/模块名禁用空格与大写,Odoo 要求 snake_case。
- 改 Python 后用
-u升级模块(仅 XML 视图改动有时需重启即可),改 manifest 的depends后也要升级。
互见
- related:
odoo-localization-compliance—— 国家级财税/电子发票合规,常作为模块开发后的会计层配置。 - 同源但尚未收录(如需可后续采编):
odoo-orm-expert(深挖 ORM 模式)、odoo-xml-views-builder(视图 XML)、odoo-security-rules(记录级权限)、odoo-automated-tests(测试)。
本条采编自 sickn33/antigravity-awesome-skills(MIT)。