Ir al contenido

Vistas kanban en Odoo 19: la plantilla card y dos errores que los tests no ven

Estructura card/menu, campos que hay que declarar y por qué un kanban «de dashboard» se cuela en otras acciones
15 de octubre de 2026 por
Vistas kanban en Odoo 19: la plantilla card y dos errores que los tests no ven
ATEMI, Aitor Atencia

Odoo · Vistas · Kanban

La kanban es la vista que más ha cambiado en las últimas versiones de Odoo, y la que más código antiguo arrastra: plantillas kanban-box, clases oe_kanban_global_click, menús desplegables montados a mano. En Odoo 19 la estructura es más simple, pero tiene dos trampas con algo en común: el servidor acepta la vista sin quejarse y el fallo solo aparece al renderizarla en el navegador.

Logo Odoo
Si la kanban solo se ha probado con get_view(), no se ha probado.

Estructura

Una kanban mínima en Odoo 19

La tarjeta se define en una plantilla llamada card; el menú de los tres puntos, en otra llamada menu. Dentro de la tarjeta puedes usar <aside> para una imagen lateral, <main> para el contenido y <footer> para la fila inferior. Abrir el registro al hacer clic ya es el comportamiento por defecto.

<record id="fleet_trip_view_kanban" model="ir.ui.view">
    <field name="name">fleet.trip.view.kanban</field>
    <field name="model">fleet.trip</field>
    <field name="arch" type="xml">
        <kanban default_group_by="state">
            <field name="is_late"/>   <!-- solo se usa en t-if: hay que declararlo -->
            <templates>
                <t t-name="menu">
                    <a role="menuitem" type="object" name="action_close"
                       class="dropdown-item">Close</a>
                </t>
                <t t-name="card" class="flex-row">
                    <aside>
                        <field name="vehicle_id" widget="image"
                               options="{'preview_image': 'image_128'}"/>
                    </aside>
                    <main class="ms-2">
                        <field name="name" class="fw-bold"/>
                        <span t-if="record.is_late.raw_value"
                              class="badge text-bg-danger">Late</span>
                        <footer>
                            <field name="date_start"/>
                            <field name="user_id" widget="many2one_avatar_user"
                                   class="ms-auto"/>
                        </footer>
                    </main>
                </t>
            </templates>
        </kanban>
    </field>
</record>

Trampa 1

kanban-box ya no existe

Hasta Odoo 16 la tarjeta se llamaba kanban-box. En Odoo 19 ese nombre no se reconoce, pero nada lo valida en el servidor: la vista se guarda, get_view() la devuelve y los tests que comprueban el arch pasan. Al abrir el menú, el cliente lanza OwlError: Missing 'card' template y el usuario ve la pantalla de error.

Trampa 2

record.campo sin <field>

El cliente solo carga los campos que aparecen como <field> en el arch. Si usas record.is_late.raw_value en un t-if pero is_late no aparece como <field> ni dentro de la tarjeta ni como hijo directo de <kanban>, el render del primer registro falla con Cannot read properties of undefined (reading 'raw_value'). Como con la trampa anterior, el servidor no se entera. Un test que parsea el arch y cruza ambas listas lo detecta antes del despliegue:

import re
from lxml import etree


def test_kanban_record_refs_are_declared(self):
    arch = self.env["fleet.trip"].get_view(view_type="kanban")["arch"]
    root = etree.fromstring(arch)
    declared = {f.get("name") for f in root.iter("field")}
    used = set(re.findall(r"record\.(\w+)\.", arch))
    self.assertFalse(used - declared, "record.X sin <field> en la kanban")

Arquitectura

Una kanban no es un dashboard

Es tentador crear una kanban «especial» con contadores y badges para usarla como panel en una acción concreta. El problema: una vista kanban registrada para un modelo se ofrece en el selector de vistas de todas las acciones de ese modelo que incluyan el modo kanban, no solo en la que pensabas. Si el panel necesita datos agregados o un diseño propio, lo correcto es una acción de cliente con un componente OWL (ver OWL en Odoo 19) que pida los datos a un método del modelo.

Antes (≤ 16)Odoo 19
<t t-name="kanban-box"><t t-name="card">
Dropdown montado a mano con o_dropdown_kanban<t t-name="menu"> con dropdown-item
oe_kanban_global_clickPor defecto; ya no hace falta
Divs con clases o_kanban_record_*<aside>, <main>, <footer>
kanban_image() en el template<field widget="image">

Resumen

En Odoo 19 la tarjeta es card y el menú es menu; todo campo leído con record.X debe aparecer como <field>; y un panel con datos agregados es una acción de cliente, no una kanban. Ninguno de los dos errores sale en los tests de servidor: abre la vista en el navegador al menos una vez antes de dar el trabajo por terminado.

en Odoo
Record rules en profundidad: OR, AND y la regla que abre más de lo que crees
Cómo combina Odoo las reglas globales y las de grupo, y qué puede usar un domain_force