Práctica: Módulo viajes. Parte 4
1. Extensión del modelo Partner con herencia (inherit = 'res.partner') #
Este código extiende el modelo res.partner en Odoo para distinguir a los conductores de otros contactos y permitir que se vean los viajes en los que han participado.
Añade el fichero
models/PartnerModel.py
1# -*- coding: utf-8 -*- 2from odoo import models, fields, api 3 4 5class Partner(models.Model): 6 _inherit = 'res.partner' 7 8 conductor = fields.Boolean("Conductor", default=False) 9 10 viaje_ids = fields.Many2many('viajes.viaje', 11 string="Viajes realizados", readonly=True)
🔹 1. _inherit = 'res.partner'
- 📌 Este modelo no crea una nueva tabla en la base de datos.
- 🔄 Extiende el modelo
res.partner, que ya gestiona contactos y clientes en Odoo. - 📂 Nos permite añadir nuevos campos sin modificar la estructura original de Odoo.
📌 Beneficio: Permite que los conductores sean gestionados como contactos normales, sin necesidad de un modelo separado.
🔹 2. Campo conductor (Booleano)
1conductor = fields.Boolean("Conductor", default=False)
- 🏷️ Añade una casilla de verificación en
res.partnerpara indicar si un contacto es conductor o no. - 🔄 Por defecto está en
False, es decir, un contacto no es conductor a menos que se marque manualmente. - 👥 Puede ser usado en filtros para listar solo los conductores.
📌 Beneficio: Permite diferenciar entre clientes, proveedores y conductores dentro del mismo modelo.
🔹 3. Campo viaje_ids (Many2many con viajes.viaje)
1viaje_ids = fields.Many2many('viajes.viaje', 2 string="Viajes realizados", readonly=True)
- Muestra en
res.partneruna lista de los viajes en los que ha participado el contacto. - 📂 Tipo
Many2many→ Un conductor puede haber realizado muchos viajes, y un viaje puede tener varios conductores o pasajeros. - 🔒
readonly=True→ Los viajes no pueden modificarse desde la vista deres.partner; solo se muestran.
📌 Beneficio: Permite ver el historial de viajes de cada conductor sin necesidad de acceder a otro módulo.
2. Importa los modelos en init.py #
Este archivo se encarga de importar los modelos de la aplicación para que Odoo los reconozca y los cargue al iniciar el módulo.
Modifica el fichero
models/__init__.py
1# -*- coding: utf-8 -*- 2 3from . import VehiculoModel 4from . import ViajeModel 5from . import PartnerModel
3. Incorpora los cambios en el módulo #
Actualiza el fichero
__manifest__.py
1....... 2 3 'version': '1.0', 4 5 # any module necessary for this one to work correctly 6 'depends': ['base'], 7 8 # always loaded 9 'data': [ 10 'security/ir.model.access.csv', 11 'views/vehiculo.xml', 12 'views/viaje.xml', 13 'views/partner.xml', 14 'views/menus.xml' 15 ], 16 # only loaded in demonstration mode 17 'demo': [ 18 'demo/demo.xml', 19 'demo/demo.viaje.xml', 20 ], 21 22 ......
4. Crea una acción de ventana para ver los contactos #
Este código define una acción de ventana (ir.actions.act_window) que permite acceder a la lista de contactos (res.partner) en Odoo.
Actualiza el fichero
views/partner.xml
1<odoo> 2 <data> 3 <record model="ir.actions.act_window" id="contact_list_action"> 4 <field name="name">Contacts</field> 5 <field name="res_model">res.partner</field> 6 <field name="view_mode">list,form</field> 7 </record> 8 </data> 9</odoo>
5. Actualiza el menú de la aplicación #
Este código añade una nueva entrada de menú en la barra de navegación de Odoo para acceder a la lista de contactos.
Actualiza el fichero
views/menus.xml
1<odoo> 2 <data> 3 <menuitem id="main_viajes_menu" name="Viajes" /> 4 5 <menuitem id="viajes_menu" name="Elementos" parent="main_viajes_menu" /> 6 7 <menuitem id="vehiculo_menu" name="Vehiculos" parent="viajes_menu" action="vehiculo_list_action" /> 8 9 <menuitem id="viaje_menu" name="Viajes" parent="viajes_menu" action="viaje_list_action" /> 10 11 <menuitem id="configuration_menu" name="Configuration" parent="main_viajes_menu" /> 12 13 <menuitem id="contact_menu" name="Viajeros" parent="configuration_menu" action="contact_list_action" /> 14 </data> 15</odoo>
6. Actualiza la vista de formulario de res.partner #
Este código extiende la vista de formulario de contactos (res.partner) en Odoo para incluir información sobre los viajes realizados por los conductores.
Actualiza el fichero
views/partner.xml
1<odoo> 2 <data> 3 4 <record model="ir.ui.view" id="partner_conductor_form_view"> 5 <field name="name">partner.conductor</field> 6 <field name="model">res.partner</field> 7 <field name="inherit_id" ref="base.view_partner_form" /> 8 <field name="arch" type="xml"> 9 <notebook position="inside"> 10 <page string="Viajes realizados"> 11 <group> 12 <field name="conductor" /> 13 <field name="viaje_ids" /> 14 </group> 15 </page> 16 </notebook> 17 </field> 18 </record> 19 20 <record model="ir.actions.act_window" id="contact_list_action"> 21 <field name="name">Contacts</field> 22 <field name="res_model">res.partner</field> 23 <field name="view_mode">list,form</field> 24 </record> 25 26 </data> 27</odoo>
7. Solucionando el error: columna no existe #
Si obtienes el ERROR: column res_partner.conductor does not exist
-
Comenta el import de PartnerModel.py en el archivo init
#from . import PartnerModel -
reinicia el servidor
-
Selecciona tu módulo viajes y desinstálalo.
-
Vuelve a añadir el import PartnerModel.py en __ init__
from . import PartnerModel -
reinicia el servidor
-
Instalar el módulo viajes de nuevo
Resumen del tema
Conceptos clave #
- Herencia de Modelos Nativos (
_inherit = 'res.partner'): extensión del modelo de contactos de Odoo para incorporar campos de negocio (conductorbooleano yviaje_ids Many2many). - Extensión de Vistas Nativas: uso de
inherit_id="base.view_partner_form"y posición<notebook position="inside">para añadir pestañas al formulario estándar de contactos sin modificar el módulobase. - Menú de Configuración de Contactos: acción de ventana y acceso a contactos filtrados bajo el menú de configuración del módulo.
- Resolución de Dependencias de Esquema en Base de Datos: actualización y reinstalación de módulos ante inconsistencias de columnas añadidas a tablas heredadas.
Qué debes recordar #
La herencia con _inherit en Python e inherit_id con <notebook position="inside"> en XML permite enriquecer modelos estándar como res.partner de forma modular y limpia.