关于 odoo-upgrade
odoo-upgrade 面向将 Odoo 模块升级到 14–19 版的开发者,提供分阶段流程及各版本迁移指引,涵盖转换、验证和测试。
主要功能
- 01分阶段升级流程
- 02XML 与视图迁移指引
- 03Python API 迁移说明
- 04JavaScript 与 OWL 更新
- 05主题和 Bootstrap 变更
- 06数据迁移模式
适用场景
- 01为模块升级到新版 Odoo 做准备
- 02解决前端 RPC 兼容性错误
- 03更新 XML 视图和门户模板
- 04规划模型与字段的数据迁移
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ahmed-lakosha/ odoo-plugins --skill odoo-upgrade安装后在 Claude Code 中输入/odoo-upgrade确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference/error_catalog.mdodoo18_to_19.mdscripts/__init__.pycli.pyprecheck.pyupgrade.pyutils.pyvalidate.pyscripts/transforms/__init__.pyjs_transforms.pymanifest.pypy_transforms.pyxml_transforms.py详细介绍
Odoo 升级助手 v5.0
适用场景
在以下情况启用:
- 在不同版本(14-19)之间升级 Odoo 模块
- 修复版本兼容性错误
- 迁移主题或自定义模块
- 解决前端中的 RPC 服务错误
- 转换 XML 视图(tree->list、搜索分组)
- 更新 Odoo 18/19 主题的 SCSS 变量
- 修复门户视图 XPath 继承错误
- 将 JavaScript 从 OWL v1 迁移到 v2
升级工作流
- 分析 - 阅读
__manifest__.py,识别源版本,扫描所有文件 - 备份 - 修改前创建带时间戳的备份
- 预检查 - 运行
scripts/cli.py precheck <path> --target <version>以识别所有问题 - 转换 - 按以下顺序应用转换:manifest、XML、Python、JS、SCSS
- 验证 - 运行
scripts/cli.py validate <path>检查语法 - 测试 - 安装模块:
python -m odoo -d DB -i MODULE --stop-after-init
XML/视图转换
Tree 转 List(Odoo 19)
<tree> -> <list>, </tree> -> </list>
tree,form -> list,form
//tree -> //list
edit="1" attribute
搜索视图(Odoo 19)
移除 <group> 标签——将筛选器放在根级别。在 group_by 筛选器前添加 <separator/>。
看板模板(Odoo 19)
t-name="kanban-box" -> t-name="card"。移除 js_class="crm_kanban"。
定时任务(Odoo 19)
移除 <field name="numbercall">——该字段已不存在。
表单视图上下文(Odoo 19)
在上下文表达式中将 active_id 替换为 id。
片段选项(Odoo 19)
移除继承 website.snippet_options 的模板——系统已重新设计。
将 Attrs 转为内联属性(Odoo 18/19)
attrs="{'invisible': [('state','=','draft')]}" -> invisible="state == 'draft'"
Python API 迁移
Slug/Unslug(Odoo 18+)
# Old: from odoo.addons.http_routing.models.ir_http import slug
# New: use request.env['ir.http']._slug(value)
URL For(Odoo 19)
# Old: from odoo.addons.http_routing.models.ir_http import url_for
# New: self.env['ir.http']._url_for('/path')
控制器类型(Odoo 19)
在 @http.route 装饰器中将 type='json' 替换为 type='jsonrpc'。
视图模式(Odoo 19)
在 Python 字典中将 'view_mode': 'tree' 替换为 'view_mode': 'list'。
JavaScript/OWL 迁移
RPC 服务(Odoo 19)
前端/公共组件中无法使用 RPC 服务。将 useService("rpc") 替换为使用 fetch API、并处理 CSRF 令牌的 _jsonRpc 辅助方法。
OWL 生命周期钩子(Odoo 18+)
| OWL 1.x(Odoo 14-17) | OWL 2.0(Odoo 18+) |
|---|---|
constructor(parent, props) | setup() |
willStart() | onWillStart(callback) |
mounted() | onMounted(callback) |
patched() | onPatched(callback) |
willUnmount() | onWillUnmount(callback) |
willUpdateProps() | onWillUpdateProps(callback) |
主题 SCSS 变量(Odoo 19)
使用带 $o-theme-* 前缀的变量,而不是 Bootstrap 原生变量名:
$headings-font-weight->$o-theme-headings-font-weight$font-size-base->$o-theme-font-size-base
颜色调色板必须包含 'menu'、'footer'、'copyright' 赋值:
$o-color-palettes: map-merge($o-color-palettes, (
'my_theme': (
'o-color-1': #124F81,
'menu': 1,
'footer': 4,
'copyright': 5,
),
));
门户视图 XPath 迁移(Odoo 19)
Sale 门户模板已重构,改用命名选择器:
表头:th[@id='product_qty_header']、th[@id='product_unit_price_header']、th[@id='product_discount_header']、th[@id='taxes_header']、th[@id='subtotal_header']
正文:tr[@name='tr_product']、td[@name='td_product_name']、td[@name='td_product_quantity']、td[@name='td_product_priceunit']、td[@name='td_product_discount']、td[@name='td_product_taxes']、td[@name='td_product_subtotal']
邮件模板迁移(Odoo 19)
从格式化辅助函数中移除 env 参数:
format_datetime(env, object.date_start)
format_datetime(object.date_start)
XML 实体编码——使用数字引用:
© -> ©、 ->  、— -> —
Bootstrap 4 到 5 的类迁移
| Bootstrap 4 | Bootstrap 5 |
|---|---|
ml-*/mr-* | ms-*/me-* |
pl-*/pr-* | ps-*/pe-* |
text-left/text-right | text-start/text-end |
float-left/float-right | float-start/float-end |
sr-only | visually-hidden |
badge-primary | bg-primary |
font-weight-bold | fw-bold |
no-gutters | g-0 |
数据迁移脚本
将迁移脚本放在 module/migrations/VERSION/ 下:
pre-migrate.py- ORM 更新前(仅使用原始 SQL)post-migrate.py- ORM 更新后(可使用 env/ORM)end-migrate.py- 所有模块更新后(清理)
每个脚本都必须定义 def migrate(cr, version):,并使用 if not version: return 进行保护。
常见模式:
| 模式 | 迁移前 | 迁移后 |
|---|---|---|
| 字段重命名 | ALTER TABLE RENAME COLUMN | 更新视图 |
| 选择字段转为 M2O | 备份值 | 映射到记录 |
| 添加必填字段 | 无需操作 | 填充默认值 |
| 模型重命名 | 重命名表和 ir_model_data | 更新外键 |
使用 openupgradelib:rename_fields()、rename_models()、rename_xmlids()、rename_columns()、logged_query()。
常见错误速查
| 错误 | 原因 | 修复方法 |
|---|---|---|
| Service rpc not available | 在前端使用 useService("rpc") | 替换为 _jsonRpc helper |
| Invalid field numbercall | 字段已移除 | 从 cron XML 中移除 |
| Invalid view definition (search) | 在 search 中使用 <group> | 移除 group 标签 |
| Missing card template | kanban-box 已重命名 | 使用 t-name="card" |
| Cannot import slug | 导入位置已更改 | 使用兼容性包装器 |
| website.snippet_options not found | 系统已重新设计 | 移除该模板 |
| active_id not found | 上下文已更改 | 替换为 id |
特定版本说明
Odoo 14 到 15
Bootstrap 4.x -> 5.x,移除 t-use-call,支付服务商 API 变更,left/right -> start/end
Odoo 15 到 16
标准化 Bootstrap 5.1.3,Web 框架重组,开始采用 OWL v1
Odoo 16 到 17
全面采用 OWL v1,组件系统变更,publicWidget API 稳定化
Odoo 17 到 18
开始从 OWL v1 升级到 v2,XML 小幅变更,引入片段分组系统
Odoo 18 到 19
前端重大改版:移除 RPC 服务,片段系统全面改版,kanban-box->card,禁止在 search 中使用 ,tree->list,重构门户模板,邮件模板辅助工具变更,移除 cron numbercall