Ir al contenido

Mixins imprescindibles en Odoo: mail.thread, mail.activity.mixin y utm.mixin

Qué aporta cada mixin y cuándo no usarlos (enlace con SOLID)
17 de junio de 2026 por
Mixins imprescindibles en Odoo: mail.thread, mail.activity.mixin y utm.mixin
Aitor Atencia

Odoo · Mixins · Arquitectura

En Odoo, los mixins son la forma más limpia de añadir comportamiento transversal sin inflar cada modelo. mail.thread trae chatter, mail.activity.mixin las actividades y utm.mixin el tracking de campañas. El error habitual: heredarlos todos «por si acaso» y violar el principio de responsabilidad única.

Logo Odoo Composición de mixins
Los mixins componen capacidades; no sustituyen un diseño de modelo coherente.

Concepto

¿Qué es un mixin en Odoo?

Un mixin es un modelo abstracto (_name con prefijo mail., utm., etc.) que aporta campos, métodos y vistas al heredarlo en tu modelo con _inherit:

class DiagnosticTest(models.Model):
    _name = 'diagnostic.test'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = 'Diagnostic Test'

Odoo fusiona automáticamente campos como message_ids, activity_ids y la lógica asociada. No duplicas código: reutilizas infraestructura probada por millones de instalaciones.

SOLID aplicado: un mixin = una responsabilidad. Si tu modelo de catálogo interno no necesita historial de mensajes, no añadas mail.thread.

mail.thread

mail.thread — chatter y seguimiento

AportaCampos / métodos claveCuándo usarlo
Chatter en formulariomessage_ids, message_follower_idsProcesos con comunicación interna
Tracking de cambiostracking=True en camposEstados, asignaciones, fechas críticas
Notificaciones emailmessage_post, suscriptoresFlujos que avisan al equipo o cliente
Adjuntos en hiloir.attachment vinculadosDocumentos asociados al registro
class ProjectTask(models.Model):
    _inherit = ['project.task', 'mail.thread']

    state = fields.Selection(
        selection=[('open', 'Open'), ('done', 'Done')],
        tracking=True,  # Aparece en el chatter automáticamente
    )

    def action_notify_team(self):
        self.message_post(
            body='Task reassigned. Please review.',
            subtype_xmlid='mail.mt_comment',
        )

mail.activity.mixin

mail.activity.mixin — actividades y recordatorios

Añade el widget de actividades (llamadas, reuniones, tareas pendientes) y los métodos para programarlas:

class CrmLead(models.Model):
    _inherit = ['crm.lead', 'mail.activity.mixin']

    def action_schedule_followup(self):
        self.activity_schedule(
            'mail.mail_activity_data_call',
            date_deadline=fields.Date.today() + timedelta(days=3),
            summary='Follow up on proposal',
            user_id=self.user_id.id,
        )

Combinación habitual en CRM, proyectos y helpdesk. Requiere dependencia del módulo mail (casi siempre instalado).

Backend Odoo con chatter
Chatter + actividades en un formulario típico de Odoo.

utm.mixin

utm.mixin — campañas y atribución

Añade campos de marketing UTM para rastrear el origen de oportunidades, pedidos o leads:

class SaleOrder(models.Model):
    _inherit = ['sale.order', 'utm.mixin']
    # Hereda: campaign_id, medium_id, source_id
CampoModeloUso típico
campaign_idutm.campaignCampaña de marketing (ej. «Black Friday 2026»)
medium_idutm.mediumCanal (email, CPC, redes)
source_idutm.sourceOrigen concreto (newsletter, Google Ads)

Úsalo en modelos que participan en embudos comerciales: crm.lead, sale.order, formularios web. En modelos puramente internos (configuración, catálogos técnicos) es ruido innecesario.

Decisión

¿Qué mixin necesito?

mail.thread

  • Procesos con estados y equipo
  • Auditoría de cambios visible
  • Comunicación cliente/interna

mail.activity.mixin

  • Flujos con tareas pendientes
  • SLA y seguimiento comercial
  • Recordatorios por usuario

utm.mixin

  • Atribución de ventas/leads
  • Integración website / marketing
  • Reporting por campaña

Vistas

Habilitar chatter en la vista form

<record id="view_diagnostic_test_form" model="ir.ui.view">
    <field name="name">diagnostic.test.form</field>
    <field name="model">diagnostic.test</field>
    <field name="arch" type="xml">
        <form>
            <sheet>...</sheet>
            <chatter/>
        </form>
    </field>
</record>

Sin <chatter/> en la vista, los mixins de mail existen pero el usuario no ve el widget. Para actividades, el chatter las incluye automáticamente.

Antipatrones

Cuándo no usar mixins

SituaciónProblemaAlternativa
Modelo transitorio (TransientModel)Chatter sin sentido en wizardsSin mixins de mail
Tablas de configuraciónRuido en UI y BDLog en ir.logging o modelo de auditoría dedicado
Alta cardinalidad (millones de filas)mail_message explotaTracking selectivo o modelo de eventos ligero
Copiar mixins «por costumbre»Violación SRP, dependencias extraLista explícita en spec del módulo

Resumen

mail.thread para comunicación y tracking, mail.activity.mixin para tareas programadas, utm.mixin para atribución de marketing. Hereda solo lo que el proceso de negocio necesita, declara dependencias en el manifest y añade <chatter/> en la vista. Menos mixins = modelos más rápidos, más legibles y más alineados con SOLID.

en Odoo
Constraints en Odoo 19: @api.constrains vs models.Constraint
Migración de _sql_constraints, unicidad y validaciones de negocio