视图继承

视图继承和 XPath 在 Odoo 里是怎么拼成最终页面的

从 ir.ui.view 的 inherit_id、mode、_compute_invalid_locators 和 _check_xml 讲清楚,为什么一个 xpath 写错会让整张视图校验失败。

Odoo 开发 前端
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 12 阅读

先说结论

Odoo 的视图继承,不是“在 XML 上随便加几个 xpath”。

它其实是一个完整的组装流程:

  • 先找到基础视图
  • 再把所有扩展视图按顺序叠上去
  • 每个 xpath 都会被验证
  • 有问题的定位器会被标出来
  • 最终拼成一个组合后的 arch

所以,视图继承的本质不是“改一小段 XML”,而是 把多个视图规格合成最终页面


inherit_idmode 决定了继承方式

ir.ui.view 里,两个字段最重要:

  • inherit_id
  • mode

源码注释已经把行为说得很清楚:

extension 模式

如果这个视图是 extension:

  • Odoo 先找到最近的 primary view
  • 再把同模型下的扩展视图叠加上去

primary 模式

如果这个视图是 primary:

  • Odoo 先把底层 primary 视图完全解析出来
  • 再把当前视图自己的 inheritance specs 叠上去

这意味着 mode 不只是一个标签,而是决定了“先谁后谁”的拼装方式。


为什么 XPath 校验这么严格

_valid_inheritance() 里,Odoo 会检查继承表达式。

它有两个很实用的约束:

  1. 不能拿被翻译的属性当选择器
  2. class 选择不要直接写死,最好用 hasclass()

这个设计的原因很简单:

  • 翻译会让文本类选择器不稳定
  • 直接写 @class='...' 很脆弱
  • 视图继承需要可维护,而不是“今天能跑,明天就坏”

所以 Odoo 更推荐稳定定位,而不是依赖易变文本。


_compute_invalid_locators() 会帮你找错位点

这是一个非常贴心的调试机制。

当继承视图有问题时,Odoo 不只是报一个“XML 错了”,而是会尝试找出:

  • 哪个 locator 找不到目标
  • 哪个 xpath 语法有问题
  • 哪个子 spec 失效了

它会先把上层视图组合起来,再逐个分析当前视图里的 specs。

这说明一个很重要的事实:

后面的 xpath 可能依赖前面的 xpath。

所以 Odoo 是按顺序应用 spec 的,不是一次性静态判断完就结束。


apply_inheritance_specs() 才是“真正改页面”的地方

当一个视图通过校验后,真正的合成动作由 apply_inheritance_specs() 完成。

它会根据 spec 的 position 执行不同操作,比如:

  • before
  • after
  • inside
  • replace
  • attributes
  • move

你可以把它理解成:

xpath 负责“找位置”,position 负责“怎么改”,apply_inheritance_specs 负责“真正落地”。

这三者缺一不可。


新手最容易踩的 4 个坑

1)拿中文文案做定位

页面文本会变,翻译也会变,太脆弱。

2)盯着某个具体节点顺序不放

父视图一升级,节点位置可能就变了。

3)在 class 上直接写死匹配

源码已经提醒你:优先用 hasclass()

4)以为一个 xpath 写错只是“局部坏掉”

在 Odoo 里,继承校验失败可能会影响整张组合视图。


实战建议

如果你在改视图,建议按这个思路:

  1. 先找稳定锚点,尽量用 id、name、数据字段或结构节点
  2. 再决定 position 是改属性还是替换节点
  3. 复杂页面尽量拆成多个小继承,而不是一个巨大的 xpath
  4. 如果报错,先看 invalid locator,再看父视图是否已经变化

视图继承看起来像 XML 技巧,其实本质上是 页面结构的源码治理

理解了这点,你写出来的继承就会稳很多。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。