Herencia en Odoo: la función que decide si tu código sobrevive a las actualizaciones
Extensión clásica, delegación y herencia de vistas. Las tres formas de modificar Odoo sin tocar el core —y por qué heredar en vez de copiar te ahorra cada migración.
Forma parte de nuestra guía completa: Desarrollo de módulos en Odoo.
Si tuviera que quedarme con una sola idea para explicar por qué unos Odoo envejecen bien y otros se convierten en una pesadilla, sería esta: la herencia. Es el mecanismo que te deja añadir, modificar y ampliar casi cualquier cosa de Odoo —un modelo del core, una vista estándar, un método de negocio— sin tocar el código original. Y "sin tocar el original" no es una preferencia estética: es lo único que hace que tu desarrollo sobreviva cuando Odoo saca la siguiente versión.
El problema es que "herencia" en Odoo significa tres cosas distintas, y mezclarlas es fuente constante de confusión. Vamos a separarlas.
1. Extensión clásica: añadir a algo que ya existe
Es la que usarás el 90% del tiempo. Declaras _inherit con el nombre de un modelo existente y, sin crear una tabla nueva, le añades campos, métodos o sobreescribes su comportamiento.
from odoo import models, fields
class SaleOrder(models.Model):
_inherit = "sale.order"
delivery_zone = fields.Char(string="Zona de reparto")
Eso solo ya añade una columna a sale.order y la deja disponible en todo el sistema. La parte interesante llega cuando quieres intervenir en la lógica, por ejemplo al confirmar un pedido:
def action_confirm(self):
# tu lógica antes...
res = super().action_confirm()
# tu lógica después...
for order in self:
order.message_post(body="Pedido confirmado y zona asignada.")
return res
Ese super() es sagrado. Es lo que llama al método original de Odoo (y al de cualquier otro módulo que también lo haya extendido). Olvidarlo —o no devolver su resultado— es uno de los bugs más sutiles y desesperantes que existen: de repente "deja de funcionar algo que no tocaste". Tocaste el flujo sin darte cuenta.
2. Delegación: "es un" sin copiar
La segunda forma es menos habitual pero brillante cuando encaja. Con _inherits (ojo, con s al final) tu modelo delega en otro: por debajo guarda un enlace al modelo padre y expone todos sus campos como si fueran suyos. El ejemplo canónico es res.users, que delega en res.partner:
class Member(models.Model):
_name = "club.member"
_inherits = {"res.partner": "partner_id"}
partner_id = fields.Many2one("res.partner", required=True, ondelete="cascade")
membership_number = fields.Char()
Ahora un socio "tiene" nombre, email y teléfono sin que tú los declares, porque vive sobre un contacto. La diferencia con la extensión clásica es clave: con _inherit modificas el modelo existente; con _inherits creas un modelo nuevo que reutiliza otro por composición. Confundir _inherit y _inherits es un clásico; míralo siempre dos veces.
3. Herencia de vistas: cambiar la interfaz sin reescribirla
La tercera no toca Python: toca XML. Es la que más se hace mal. En lugar de copiar el formulario entero del core y editarlo (un suicidio de cara a las actualizaciones), apuntas con precisión quirúrgica al sitio donde quieres insertar tu campo, usando xpath y position.
<record id="view_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form.delivery</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='payment_term_id']" position="after">
<field name="delivery_zone"/>
</xpath>
</field>
</record>
"Después del campo payment_term_id, mete el mío." Eso es todo. Cuando Odoo actualice ese formulario en la próxima versión, tu añadido se reaplica encima, intacto. El que copió la vista entera, en cambio, se queda con una versión congelada del formulario de hace dos años y pierde todo lo nuevo. Lo vemos en cada migración: el módulo que "heredó bien" sube en horas; el que "copió y pegó" cuesta días.
La regla que repetimos hasta el cansancio: hereda, no copies
Todo esto se reduce a un principio que ya mencionamos en las buenas prácticas para módulos: duplicar lógica del core es deuda técnica con fecha de caducidad. La fecha es el día de la próxima actualización. Heredar cuesta un poco más de pensar al principio y se paga solo en cada salto de versión.
Mi recomendación práctica, después de bastantes migraciones: antes de escribir nada, pregúntate "¿esto ya existe en Odoo de alguna forma?". Casi siempre la respuesta es sí, y casi siempre lo correcto es extenderlo, no reinventarlo. Si entiendes esto y lo del super(), evitas la mayoría de los problemas que nos llegan en auditorías.
Por qué esto te importa aunque no programes
Si eres quien decide, la herencia explica una frase que oirás mucho: "esto es personalizable, pero hay que hacerlo bien". Un desarrollo que hereda es un activo que evoluciona contigo; uno que copia y parchea es una bomba de relojería que estalla en la siguiente versión y te ata a quien lo escribió. Saber distinguir uno de otro —o tener a alguien que lo sepa— es lo que separa un Odoo que crece de uno que se estanca.
¿Tienes módulos a medida y te preocupa cómo aguantarán la próxima actualización? En una auditoría de tu código revisamos si heredan como deben o si te espera una sorpresa. Y si vas a desarrollar desde cero, así lo hacemos en nuestro servicio de desarrollo a medida. Para los cimientos, empieza por la anatomía de un módulo y las relaciones entre modelos.
Comentarios (0)
Sé el primero en comentar.
Inicia sesión para dejar un comentario.
AccederLos comentarios se revisan antes de publicarse.
Artículos relacionados
Acciones automatizadas en Odoo: deja que el ERP haga el trabajo aburrido
Acciones de servidor, reglas de automatización y tareas planificadas: las tres piezas para que Odoo reaccione, avise y ejecute solo, sin que nadie se acuerde.
Informes PDF con QWeb en Odoo: del formulario al documento que cierra ventas
QWeb es HTML que se convierte en PDF. Te enseñamos a montar un informe, recorrer registros con t-foreach y por qué t-field te ahorra mil dolores de cabeza.
Relaciones entre modelos en Odoo: Many2one, One2many y Many2many sin liarte
Las tres relaciones que conectan tus datos, qué guardan de verdad en la base de datos y los comandos para escribirlas sin romper nada.