关于 odoo-oca-developer
面向 Odoo 模块开发者的技能,可按 OCA 规范生成和验证模块,并提供 OpenUpgrade 迁移及扩展指导。
主要功能
- 01生成符合 OCA 规范的模块结构
- 02验证文件与清单规范
- 03指导 OpenUpgrade 迁移模式
- 04支持扩展核心模块
适用场景
- 01搭建新的 Odoo 插件
- 02检查插件是否符合 OCA 规范
- 03规划使用 OpenUpgrade 的版本迁移
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ miquelalzanillas/ odoo-oca-convention-skill --skill odoo-oca-developer安装后在 Claude Code 中输入/odoo-oca-developer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/module_template/__init__.py__manifest__.pyexceptions.pyhooks.pyREADME.rstassets/module_template/controllers/__init__.pymain.pyassets/module_template/data/model_name_data.xmlassets/module_template/demo/assets.xmlmodel_name_demo.xmlassets/module_template/examples/README.rstassets/module_template/i18n/.emptyassets/module_template/migrations/8.0.1.0.0/post-migrate.pypre-migrate.pyassets/module_template/models/__init__.pyabstract_something.pymodel_name.pyassets/module_template/readme/CONFIGURE.mdCONTEXT.mdCONTRIBUTORS.mdCREDITS.mdDESCRIPTION.mdHISTORY.mdINSTALL.mdROADMAP.mdUSAGE.mdassets/module_template/readme/newsfragments/.gitkeepassets/module_template/report/__init__.pyreport_name.pyassets/module_template/security/ir.model.access.csv详细介绍
Odoo OCA 开发者
精通 Odoo 模块开发的助手,遵循 OCA 规范和最佳实践。
核心能力
1. 创建模块
基于 OCA 模板创建新的 Odoo 模块,并遵循正确的结构和规范。
快速入门:
python scripts/init_oca_module.py my_module_name --path /path/to/addons --version 17.0
提供的内容:
- 完整且符合 OCA 规范的目录结构
- 预配置的
__manifest__.py,包含必需的键 - 遵循 OCA 指南的 README 结构
- 正确的
__init__.py导入 - 示例模型、视图和安全文件
模块命名规范:
- 使用单数形式:
sale_order_import(而非sale_orders_import) - 基础模块:添加
base_前缀(例如base_location_nuts) - 本地化模块:添加
l10n_CC_前缀(例如l10n_es_pos) - 扩展模块:使用父模块作为前缀(例如
mail_forward) - 组合模块:Odoo 模块名在前(例如
crm_partner_firstname)
2. 模块结构
严格遵循 OCA 规范。详细指南请参阅 oca_conventions.md。
基本结构:
module_name/
├── __init__.py
├── __manifest__.py
├── models/
│ ├── __init__.py
│ └── <model_name>.py
├── views/
│ └── <model_name>_views.xml
├── security/
│ ├── ir.model.access.csv
│ └── <model_name>_security.xml
├── data/
│ └── <model_name>_data.xml
├── readme/
│ ├── DESCRIPTION.rst
│ ├── USAGE.rst
│ └── CONTRIBUTORS.rst
└── tests/
├── __init__.py
└── test_<feature>.py
关键原则:
- 每个模型使用一个文件:
models/sale_order.py - 视图名称与模型名称相匹配:
views/sale_order_views.xml - 演示数据添加
_demo后缀:demo/sale_order_demo.xml - 迁移文件放在带版本号的目录中:
migrations/17.0.1.0.0/
3. 遵循 OCA 规范
__manifest__.py 要点:
{
'name': 'Module Name',
'version': '17.0.1.0.0', # {odoo}.x.y.z format
'category': 'Sales',
'license': 'AGPL-3', # or LGPL-3
'author': 'Your Company, Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/<repository>',
'depends': ['base', 'sale'],
'data': [
'security/ir.model.access.csv',
'views/model_name_views.xml',
],
'installable': True,
}
Python 代码结构:
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class SaleOrder(models.Model):
_inherit = 'sale.order'
# Fields
custom_field = fields.Char(string="Custom Field")
# Compute methods
@api.depends('order_line')
def _compute_total(self):
for order in self:
order.total = sum(order.order_line.mapped('price_total'))
# Business methods
def action_custom(self):
self.ensure_one()
# Implementation
XML 命名规范:
- 视图:
<model_name>_view_<type>(例如sale_order_view_form) - 操作:
<model_name>_action(例如sale_order_action) - 菜单:
<model_name>_menu - 分组:
<model_name>_group_<name> - 演示数据:添加
_demo后缀
4. 使用 OpenUpgrade 迁移模块
按照 OpenUpgrade 模式在不同 Odoo 版本之间迁移模块。完整指南请参阅 openupgrade_migration.md。
迁移结构:
module_name/
└── migrations/
└── 17.0.1.0.0/
├── pre-migration.py
├── post-migration.py
└── noupdate_changes.xml
迁移前示例:
from openupgradelib import openupgrade
@openupgrade.migrate()
def migrate(env, version):
# Rename fields before module loads
openupgrade.rename_fields(env, [
('sale.order', 'sale_order', 'old_field', 'new_field'),
])
# Rename models
openupgrade.rename_models(env.cr, [
('old.model', 'new.model'),
])
迁移后示例:
from openupgradelib import openupgrade
@openupgrade.migrate()
def migrate(env, version):
# Map old values to new
openupgrade.map_values(
env.cr,
openupgrade.get_legacy_name('state'),
'state',
[('draft', 'pending'), ('confirm', 'confirmed')],
table='sale_order',
)
# Recompute fields
env['sale.order'].search([])._compute_total()
常见迁移任务:
- 重命名字段:
openupgrade.rename_fields() - 重命名模型:
openupgrade.rename_models() - 重命名表:
openupgrade.rename_tables() - 映射值:
openupgrade.map_values() - 删除过时数据:
openupgrade.delete_records_safely_by_xml_id()
5. 扩展模块
按照 OCA 模式扩展 Odoo 核心模块。
继承现有模型:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
custom_field = fields.Char(string="Custom Info")
扩展现有视图:
<record id="res_partner_view_form" model="ir.ui.view">
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='email']" position="after">
<field name="custom_field"/>
</xpath>
</field>
</record>
模块依赖项:
- 始终在
__manifest__.py中声明依赖项 - 使用
depends键声明 Odoo 核心模块或 OCA 模块 - 使用
external_dependencies声明 Python 软件包 - 在 README 中说明安装要求
6. 验证与质量
验证模块结构:
python scripts/validate_module.py /path/to/module
检查内容:
- 是否存在必需文件(
__init__.py、__manifest__.py) - 清单文件是否完整(必需的键)
- OCA 作者署名
- 许可证合规性(AGPL-3 或 LGPL-3)
- 版本格式(x.y.z.w.v)
- 文件命名规范
- 目录结构
代码质量工具:
# Install pre-commit for OCA checks
pip install pre-commit
pre-commit install
# Run checks
pre-commit run --all-files
# Run specific checks
flake8 module_name/
pylint --load-plugins=pylint_odoo module_name/
工作流决策树
“我需要创建一个新的 Odoo 模块”
→ 使用 scripts/init_oca_module.py 生成符合 OCA 规范的结构
→ 编辑 __manifest__.py,填写模块详情
→ 在 models/ 目录中创建模型
→ 在 views/ 目录中创建视图
→ 在 security/ 中添加安全规则
→ 更新 readme/ 文档
→ 运行验证:scripts/validate_module.py
“我需要将模块迁移到新的 Odoo 版本”
→ 检查 OpenUpgrade,了解不兼容的变更
→ 创建迁移文件夹:migrations/<new_version>/
→ 编写用于架构变更的迁移前脚本
→ 编写用于数据转换的迁移后脚本
→ 在生产数据库副本上测试
→ 参阅 openupgrade_migration.md
“我需要扩展 Odoo 核心模块”
→ 创建新模块,并在 depends 中添加核心模块
→ 使用 _inherit 扩展模型
→ 使用 inherit_id 扩展视图
→ 遵循 OCA 命名规范:<core_module>_<feature>
→ 让改动尽可能精简且聚焦
“我不确定我的模块是否遵循 OCA 规范”
→ 运行 scripts/validate_module.py
→ 查看 oca_conventions.md
→ 检查 manifest.py 中是否包含必需的键
→ 验证文件命名和结构
→ 确保注明 OCA 作者署名
资源
scripts/
- init_oca_module.py:创建符合 OCA 规范结构的新 Odoo 模块
- validate_module.py:根据 OCA 规范验证模块
references/
- oca_conventions.md:完整的 OCA 编码标准和模块结构指南
- openupgrade_migration.md:OpenUpgrade 迁移模式和最佳实践
assets/
- module_template/:官方 OCA 模块模板,包含完整的目录结构
最佳实践
模块开发
- 从 OCA 模板开始:
scripts/init_oca_module.py - 严格遵循命名规范
- 每个模型单独使用一个文件
- 将模型、视图和数据分开
- 使用符合 OCA 模式的、有意义的 xmlid
- 编写全面的测试
- 在 readme/ 文件夹中编写文档
代码质量
- Python 代码遵循 PEP8
- XML 使用 4 个空格缩进
- 避免 SQL 注入漏洞
- 未经充分理由,绝不绕过 ORM
- 绝不手动提交事务
- 使用
_logger.debug()记录导入错误 - 正确处理外部依赖
Git 提交
格式:[TAG] module_name: short summary
常用标签:
[ADD]- 新功能/模块[FIX]- 错误修复[REF]- 重构[IMP]- 改进[MIG]- 迁移[REM]- 移除
迁移策略
- 研究目标版本的 OpenUpgrade 分析
- 检查核心模块是否有不兼容的变更
- 先在数据库副本上测试
- 为架构变更编写迁移前脚本
- 为数据转换编写迁移后脚本
- 在 README 中记录不兼容的变更
- 按照语义化版本规范更新版本号
常见模式
模式:添加带依赖项的计算字段
total = fields.Float(compute='_compute_total', store=True)
@api.depends('line_ids.amount')
def _compute_total(self):
for record in self:
record.total = sum(record.line_ids.mapped('amount'))
模式:安全地扩展视图
<xpath expr="//field[@name='partner_id']" position="after">
<field name="custom_field"/>
</xpath>
模式:添加安全组
<record id="group_custom" model="res.groups">
<field name="name">Custom Access</field>
<field name="category_id" ref="base.module_category_sales"/>
</record>
模式:使用值映射进行迁移
openupgrade.map_values(
env.cr,
openupgrade.get_legacy_name('old_field'),
'new_field',
[('old_value', 'new_value')],
table='model_table',
)
故障排查
模块未显示在 Apps 中
- 检查 manifest.py 中是否有
'installable': True - 验证 init.py 导入
- 运行:
odoo-bin -u module_name -d database
导入错误
- 为外部依赖添加 try-except
- 在 readme/INSTALL.rst 中记录安装说明
- 将 Python 包添加到 requirements.txt
迁移失败
- 检查迁移前脚本是否在模块加载前运行
- 在 psql 中使用
\d table验证表名/列名 - 使用
openupgrade.logged_query()进行调试 - 先在数据库副本上测试
测试失败
- 使用
tagged('post_install', '-at_install') - 使用
@users(),以最低用户权限进行测试 - 避免使用动态日期,改用
freezegun - 模拟外部服务
Quick Reference
Create module:
python scripts/init_oca_module.py my_module --version 17.0
Validate module:
python scripts/validate_module.py path/to/module
Check conventions: See oca_conventions.md
Migration guide: See openupgrade_migration.md
Module template: Copy from assets/module_template/