You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:15:29