What Are Optional Columns?
Optional columns let users customize which columns appear in Odoo list (tree) views. Instead of showing every field and overwhelming users with data, you mark certain columns as optional. Users toggle them via the column picker icon in the top-right corner of the list view.
<tree>
<field name="name"/>
<field name="partner_id"/>
<field name="amount_total"/>
<field name="date_order" optional="show"/>
<field name="user_id" optional="show"/>
<field name="payment_term_id" optional="hide"/>
<field name="company_id" optional="hide"/>
</tree>Optional Values
| Value | Behavior |
|---|---|
| (no optional) | Always visible, not toggleable |
| optional="show" | Visible by default, user can hide |
| optional="hide" | Hidden by default, user can show |
Fields without the optional attribute are always visible and do not appear in the column picker menu.
User Preferences Are Stored
When a user toggles optional columns, their preference is stored in the browser's local storage and persists across sessions. This means each user can have their own column layout without affecting other users.
Practical Examples
Sale Order List with Optional Columns
<tree decoration-info="state == 'draft'" decoration-success="state == 'sale'">
<field name="name"/>
<field name="partner_id"/>
<field name="date_order" optional="show"/>
<field name="amount_untaxed" optional="hide"/>
<field name="amount_tax" optional="hide"/>
<field name="amount_total"/>
<field name="currency_id" column_invisible="True"/>
<field name="user_id" optional="show" widget="many2one_avatar_user"/>
<field name="team_id" optional="hide"/>
<field name="state" widget="badge"
decoration-info="state == 'draft'"
decoration-success="state in ('sale','done')"/>
</tree>Product List for Inventory
<tree>
<field name="default_code" optional="show"/>
<field name="name"/>
<field name="categ_id" optional="show"/>
<field name="type" optional="hide"/>
<field name="list_price"/>
<field name="standard_price" optional="hide"/>
<field name="qty_available" optional="show"/>
<field name="virtual_available" optional="hide"/>
<field name="uom_id" optional="hide"/>
<field name="barcode" optional="hide"/>
<field name="active" optional="hide"/>
</tree>column_invisible vs optional
These serve different purposes:
| Attribute | Purpose | User Can Toggle? |
|---|---|---|
| optional="hide" | Hidden by default, user can show | Yes |
| column_invisible="True" | Always hidden (used for data access) | No |
| invisible="True" | Conditionally hidden (per row or global) | No |
Use column_invisible for fields needed by other view logic (decorations, domains) but never shown to the user. Use optional for fields the user might want to see.
Combining with Decorations
Optional columns work with all list view features:
<tree decoration-danger="amount_total > 100000">
<field name="name"/>
<field name="amount_total" decoration-bf="1"/>
<field name="margin" optional="show"
decoration-danger="margin < 0"
decoration-success="margin > 30"/>
</tree>Inheriting and Adding Optional Columns
When extending an existing list view via inheritance, you can add new optional columns:
<record id="sale_order_tree_inherit" model="ir.ui.view">
<field name="name">sale.order.tree.custom</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_tree"/>
<field name="arch" type="xml">
<field name="amount_total" position="after">
<field name="x_custom_field" optional="hide"/>
</field>
</field>
</record>You can also change an existing field to optional:
<field name="user_id" position="attributes">
<attribute name="optional">hide</attribute>
</field>Best Practices
- Core fields always visible: Name, status, and primary amount should never be optional
- Default show for commonly used: Fields most users need should be
optional="show" - Default hide for specialized: Technical fields, secondary amounts, and reference codes should be
optional="hide" - Do not overdo it: More than 5-6 optional columns makes the picker unwieldy
- Group related fields: Place related optional fields adjacent to each other
- Use with widgets: Optional columns support all widgets — badges, tags, avatars, progress bars
Optional Columns in Odoo 19
Odoo 19 has improved the optional column experience with:
- Better column picker UI with grouped sections
- Preserved column order when toggling
- Support for optional columns in embedded list views (One2many fields in forms)
- The
column_invisibleattribute replaces the oldinvisible="1"for columns that should never show
Optional columns are a simple but powerful UX improvement. They reduce visual clutter while keeping all data accessible, and they require zero Python code — just XML view changes.