Odoo.sh升级至v15:如何迁移已废弃的继承视图?
Odoo.sh 升级至v15解决模板缺失报错方案
问题背景
从v13升级到v15时,官方模块website_blog中的s_latest_posts模板被移除,导致自定义/第三方模板中继承该模板的代码(如<template id="my_s_latest_post" inherit_id="website_blog.s_latest_posts">)触发ValueError: External ID not found in the system: website_blog.s_latest_posts报错。
迁移脚本解决方案
通过Odoo.sh的预迁移、后迁移脚本禁用无效视图,完成升级后再处理视图替换。
1. pre-migrate.py(升级前禁用无效视图)
作用:在升级开始前,标记所有继承已删除模板的视图为禁用状态,避免升级时触发校验报错。
from odoo import api, SUPERUSER_ID def migrate(cr, version): if not version: return env = api.Environment(cr, SUPERUSER_ID, {}) # 查找所有继承website_blog.s_latest_posts的视图 invalid_views = env['ir.ui.view'].search([ ('inherit_id', '=', env.ref('website_blog.s_latest_posts', raise_if_not_found=False).id), ('active', '=', True) ]) # 禁用这些视图 invalid_views.write({'active': False}) # 处理调用第三方主题模板的自定义视图(替换为实际第三方模板ID) third_party_invalid = env['ir.ui.view'].search([ ('inherit_id', '=', env.ref('theme_x.s_custom_latest_post', raise_if_not_found=False).id), ('active', '=', True) ]) third_party_invalid.write({'active': False})
2. post-migrate.py(升级后标记待处理视图)
作用:升级完成后,标记需要替换的视图,方便后续开发调整。
from odoo import api, SUPERUSER_ID def migrate(cr, version): if not version: return env = api.Environment(cr, SUPERUSER_ID, {}) # 给之前禁用的继承视图添加待替换标记 invalid_views = env['ir.ui.view'].search([ ('inherit_id', '=', env.ref('website_blog.s_latest_posts', raise_if_not_found=False).id), ('active', '=', False) ]) invalid_views.write({'name': invalid_views.mapped(lambda v: f'[待替换] {v.name}')})
3. end-migrate.py(升级收尾,替换/清理视图)
作用:完成所有升级步骤后,替换无效的继承关系,或删除无用视图,恢复系统正常运行。
from odoo import api, SUPERUSER_ID def migrate(cr, version): if not version: return env = api.Environment(cr, SUPERUSER_ID, {}) # 替换继承关系:用v15中对应功能的官方模板替代原模板 invalid_views = env['ir.ui.view'].search([ ('inherit_id', '=', env.ref('website_blog.s_latest_posts', raise_if_not_found=False).id), ('active', '=', False) ]) target_template = env.ref('website_blog.blog_posts', raise_if_not_found=True) for view in invalid_views: # 更新继承ID为v15有效模板,若结构差异大需额外调整视图内容 view.write({ 'inherit_id': target_template.id, 'active': True }) # 删除完全无用的待替换视图(按需执行) env['ir.ui.view'].search([ ('name', 'like', '[待替换]%'), ('active', '=', False) ]).unlink()
注意事项
- 替换模板ID时需通过Odoo开发者模式确认v15中对应功能的官方模板外部ID。
- 第三方主题模板优先联系开发者获取v15兼容版本,无法获取时再自行修改继承关系。
- 所有脚本需先在测试环境验证,确认无误后再部署到生产环境。
内容的提问来源于stack exchange,提问作者Ahrimann Steiner
相关产品推荐
相关产品推荐

