视图继承

Odoo 视图继承不是复制粘贴:XPath 如何把字段插进原页面

用 website_sale 和 website_event_crm 的真实 XML 片段说明 inherit_id、xpath 和 position 的工作方式,以及为什么一个 XPath 就能决定整页布局。

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

很多人第一次改 Odoo 页面,都会本能地想:

我把原 XML 复制一份,改完再替换掉不就行了吗?

这通常是最容易把项目改崩的做法。

Odoo 的视图系统更像“在原图上打补丁”,而不是“整页重画”。inherit_idxpathposition 就是这套机制的三把钥匙。

先理解 inherit_id:你继承的是“节点”,不是整份文件

website_sale/views/product_views.xml 里,你会看到很多这种结构:

<record id="product_template_view_tree_website_sale" model="ir.ui.view">
    <field name="inherit_id" ref="website_sale.product_template_view_tree"/>
</record>

意思不是“把父视图抄一遍”,而是:

  • 我先认这个父视图;
  • 再只描述我要改哪一小块;
  • 最后由 Odoo 合成最终视图。

所以继承视图的核心思路是 增量修改

xpath 负责精准定位,position 负责说明怎么改

最常见的写法像这样:

<field name="default_code" position="after">
    <field name="website_id" groups="website.group_multi_website" optional="hide"/>
</field>

这句话的意思很直白:

  • 先找到 default_code 这个节点;
  • 然后在它后面插入新字段。

再看 website_event_crm/views/event_lead_rule_views.xml

<xpath expr="//field[@name='lead_creation_basis']" position="attributes">
    <attribute name="column_invisible">False</attribute>
</xpath>

这就不是插入,而是直接修改目标节点的属性。

所以 position 不是装饰,它决定的是:

  • before
  • after
  • inside
  • replace
  • attributes

不同位置对应完全不同的改法。

一个很重要的区分:插字段和改属性不是一回事

很多新手会把这两种操作混着写,最后发现视图没有按预期变化。

插入内容

适合:

  • 增加字段;
  • 增加按钮;
  • 增加提示文案;
  • 增加一段 QWeb 结构。

改属性

适合:

  • 让原字段可见或不可见;
  • readonly
  • required
  • 改列显示方式;
  • 改 class、style、widget 等属性。

这就是为什么同样是“改页面”,有时你写的是 field position="after",有时则必须用 xpath position="attributes"

website_sale 里的例子很好懂

product_template_view_tree_website_sale 会在产品列表里插入:

  • website_sequence
  • public_categ_ids
  • is_published

这些都不是重画整张列表,而是在原来产品列表的基础上补出网站销售需要的字段。

这背后的理念很清楚:

业务差异越小,视图补丁就越小。

templates.xml 里的 QWeb 继承也是同一套路

website_sale/views/templates.xml 里,像 header_hide_empty_cart_link 这种继承模板,会先继承 website_sale.header_cart_link,再通过 xpath 把 show_cart 的逻辑改掉。

这说明 QWeb 和传统 form/tree 视图虽然长得不一样,但继承思路是一致的:

  • 先定位;
  • 再插针;
  • 再让合成器生成最终页面。

新手最容易犯的三个错

1)XPath 太宽

比如匹配了多个节点,结果插进去了不该插的位置。

2)改错层

有些改动该在 form 视图做,你却在 QWeb 做;或者该在模板层改,你却在 backend tree 里硬找。

3)把 mode="primary" 当成“我想强行覆盖父视图”

primary 只是说明这个视图在某些场景下作为主要视图参与解析,不代表你可以不顾继承链随便写。

调试视图时,建议你这样想

  1. 先确认父视图是谁;
  2. 再确认你要改的是节点内容还是节点属性;
  3. 再确认 XPath 是否只命中一个目标;
  4. 最后看 position 是否真的符合你的意图。

只要这四步顺了,视图继承通常就不神秘了。

一句话总结

Odoo 视图继承不是复制粘贴,而是:

inherit_id 绑定父视图,用 xpath 找到目标节点,再用 position 精准修改原页面。

DISCUSSION

评论区

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