Skip to content

Odoo 19 Views: Complete Guide to Form, List, Kanban, and Search Views

DeployMonkey Team · March 22, 2026 20 min read

What Changed in Odoo 19 Views

If you are coming from an earlier version, these are the critical changes:

  • Odoo 18+: <tree> renamed to <list> — using <tree> still works but is deprecated
  • Odoo 17+: attrs attribute removed — use invisible, readonly, required directly as view attributes
  • Odoo 19: web_editor module removed, replaced by html_editor + html_builder

Form Views

<record id="equipment_view_form" model="ir.ui.view">
    <field name="name">equipment.form</field>
    <field name="model">equipment.item</field>
    <field name="arch" type="xml">
        <form>
            <header>
                <button name="action_confirm" type="object"
                        string="Confirm" class="btn-primary"
                        invisible="state != 'draft'"/>
                <field name="state" widget="statusbar"
                       statusbar_visible="draft,confirmed,done"/>
            </header>
            <sheet>
                <div class="oe_title">
                    <h1><field name="name" placeholder="Equipment Name"/></h1>
                </div>
                <group>
                    <group string="Details">
                        <field name="serial_number"/>
                        <field name="department_id"/>
                        <field name="assigned_to"/>
                    </group>
                    <group string="Dates">
                        <field name="purchase_date"/>
                        <field name="warranty_expiry"/>
                        <field name="days_until_warranty"
                               invisible="not warranty_expiry"/>
                    </group>
                </group>
                <notebook>
                    <page string="Maintenance History" name="maintenance">
                        <field name="maintenance_ids">
                            <list>
                                <field name="date"/>
                                <field name="type"/>
                                <field name="description"/>
                                <field name="cost"/>
                            </list>
                        </field>
                    </page>
                    <page string="Notes" name="notes">
                        <field name="notes" placeholder="Internal notes..."/>
                    </page>
                </notebook>
            </sheet>
            <div class="oe_chatter">
                <field name="message_follower_ids"/>
                <field name="activity_ids"/>
                <field name="message_ids"/>
            </div>
        </form>
    </field>
</record>

Key Form View Elements

ElementPurpose
<header>Action buttons and statusbar
<sheet>Main content area with white background
<div class="oe_title">Large title field at the top
<group>Two-column layout container
<notebook> / <page>Tabbed sections
<div class="oe_chatter">Discussion thread and activities

List Views (Formerly Tree)

<record id="equipment_view_list" model="ir.ui.view">
    <field name="name">equipment.list</field>
    <field name="model">equipment.item</field>
    <field name="arch" type="xml">
        <list decoration-danger="days_until_warranty < 30"
              decoration-warning="days_until_warranty < 90">
            <field name="name"/>
            <field name="serial_number"/>
            <field name="department_id"/>
            <field name="assigned_to"/>
            <field name="state" widget="badge"
                   decoration-success="state == 'active'"
                   decoration-info="state == 'maintenance'"/>
            <field name="warranty_expiry"/>
            <field name="days_until_warranty" optional="hide"/>
        </list>
    </field>
</record>

Important: Use <list> not <tree> in Odoo 18+. <tree> still works but is deprecated.

Kanban Views

<record id="equipment_view_kanban" model="ir.ui.view">
    <field name="name">equipment.kanban</field>
    <field name="model">equipment.item</field>
    <field name="arch" type="xml">
        <kanban default_group_by="state">
            <templates>
                <t t-name="card">
                    <field name="name" class="fw-bold fs-5"/>
                    <field name="serial_number" class="text-muted"/>
                    <div class="d-flex justify-content-between mt-2">
                        <field name="department_id"/>
                        <field name="assigned_to" widget="many2one_avatar"/>
                    </div>
                </t>
            </templates>
        </kanban>
    </field>
</record>

Search Views

<record id="equipment_view_search" model="ir.ui.view">
    <field name="name">equipment.search</field>
    <field name="model">equipment.item</field>
    <field name="arch" type="xml">
        <search>
            <field name="name"/>
            <field name="serial_number"/>
            <field name="department_id"/>
            <field name="assigned_to"/>
            <filter name="active" string="Active"
                    domain="[('state', '=', 'active')]"/>
            <filter name="maintenance" string="In Maintenance"
                    domain="[('state', '=', 'maintenance')]"/>
            <filter name="warranty_expiring" string="Warranty Expiring"
                    domain="[('days_until_warranty', '<', 90)]"/>
            <separator/>
            <group string="Group By">
                <filter name="group_department" string="Department"
                        context="{'group_by': 'department_id'}"/>
                <filter name="group_state" string="Status"
                        context="{'group_by': 'state'}"/>
                <filter name="group_assigned" string="Assigned To"
                        context="{'group_by': 'assigned_to'}"/>
            </group>
        </search>
    </field>
</record>

View Inheritance

<!-- Add a field to an existing view -->
<record id="equipment_view_form_inherit" model="ir.ui.view">
    <field name="name">equipment.form.inherit</field>
    <field name="model">equipment.item</field>
    <field name="inherit_id" ref="equipment_view_form"/>
    <field name="arch" type="xml">
        <!-- Add after a specific field -->
        <xpath expr="//field[@name='serial_number']" position="after">
            <field name="manufacturer"/>
        </xpath>

        <!-- Add a new page to the notebook -->
        <xpath expr="//notebook" position="inside">
            <page string="Warranty Info" name="warranty">
                <group>
                    <field name="warranty_provider"/>
                    <field name="warranty_type"/>
                </group>
            </page>
        </xpath>
    </field>
</record>

Common XPath Patterns

XPathMatches
//field[@name='x']Field named 'x' anywhere
//group[@string='Details']Group with string 'Details'
//page[@name='notes']Notebook page named 'notes'
//notebookThe notebook element
//sheetThe sheet element

Position Attribute

PositionEffect
afterInsert after the matched element
beforeInsert before the matched element
insideInsert as last child of matched element
replaceReplace the matched element entirely
attributesModify attributes of matched element

Conditional Visibility (Odoo 17+)

<!-- OLD (Odoo 16 and earlier) — DO NOT USE IN v17+ -->
<field name="discount" attrs="{'invisible': [('state', '!=', 'draft')]}"/>

<!-- NEW (Odoo 17+) — use direct attribute -->
<field name="discount" invisible="state != 'draft'"/>
<field name="approval_note" readonly="state == 'done'"/>
<field name="partner_id" required="state == 'confirmed'"/>

<!-- Complex conditions -->
<field name="discount" invisible="state != 'draft' or not is_manager"/>

Getting Started

Use Claude Code with an Odoo 19 CLAUDE.md to generate views with correct syntax. Deploy and test on DeployMonkey — the AI agent helps diagnose view rendering issues.