odoo-views
Odoo views
The view you edit is not the view that renders. Odoo merges the base arch with every inheriting view across the addon graph at get_view() time. An xpath that doesn't match the resolved arch silently no-ops — the field you "added" never appears and nothing is logged.
Read ground truth first. Run the odoo-introspect skill's entrypoints (Layer B) on the model: it dumps the inheritance-resolved arch, the buttons (which method/action each fires), and the view-level field modifiers (readonly/invisible/required). It also returns the inheritance_chain — the base view plus every applied extension in priority order — so you pick the right view to inherit and can see which siblings already touch your target node. Render one specific view with --view-xmlid/--view-id. Now your xpath targets exist and you won't duplicate a field.
Version floor: Odoo 17/18, through Odoo 19 (current LTS). Pre-17 deltas and the v18.1 → 19 changes → skills/odoo-introspect/references/version-matrix.md.
v17/18 breaking syntax — get this right
| Old (≤16) | Current | Since |
|---|---|---|
attrs="{'invisible': [('state','=','done')]}" |
invisible="state == 'done'" |
17.0 |
attrs for readonly/required |
readonly="<expr>" / required="<expr>" |
17.0 |
states="draft,sent" |
invisible="state not in ['draft','sent']" |
17.0 |
invisible to hide a list column |
column_invisible="<expr>" (plain invisible hides only the cell) |
17.0 |
<tree> root + view_mode="tree,form" |
<list> root + view_mode="list,form" |
18.0 |
<div class="oe_chatter"><field …/></div> |
<chatter/> (self-closing; <chatter>…fields…</chatter> to customize) |
18.0 |
t-esc / t-raw in kanban/QWeb templates |
t-out (escapes by default; t-raw removed) |
17.0 |