Práctica: Módulo viajes. Parte 3
1. Creando relaciones Many2one #
2. Agrega un campo de relación Many2one en el modelo Vehiculo, permitiendo asignar un propietario a cada vehículo. #
- 🔗 Establece una relación con
res.usersres.userses el modelo de usuarios en Odoo.- Permite seleccionar un usuario como propietario del vehículo.
- 📝 Permite crear usuarios directamente desde el formulario de vehículo
- Si el usuario no existe, se puede crear en el momento.
- 🔄 Mejora la gestión y trazabilidad de los vehículos
- Permite saber quién es el dueño de cada vehículo dentro del sistema.
Añade la relación al fichero:
models/vehiculo.py
1from odoo import models, fields, api 2 3 4class Vehiculo(models.Model): 5 _name = 'viajes.vehiculo' 6 _description = "viajes Vehiculo" 7 modelo = fields.Char(string="Modelo", required=True) 8 marca = fields.Char(string="Marca") 9 descripcion = fields.Text() 10 11 #Con la relación many2one me permite seleccionar un usuario o crearlo directamente 12 propietario_id = fields.Many2one('res.users', 13 ondelete='set null', string="Propietario", index=True) 14 15 @api.depends('modelo', 'marca') 16 def _compute_display_name(self): 17 for record in self: 18 record.display_name = f"{record.modelo} - {record.marca}" if record.marca else record.modelo
'res.users'→ Define que este campo se relaciona con el modelores.users(usuarios de Odoo).ondelete='set null'→ Si el usuario es eliminado, el campo se pone enNULLen lugar de eliminar el vehículo.string="Propietario"→ Nombre visible del campo en la interfaz de Odoo.index=True→ Optimiza las búsquedas en la base de datos._compute_display_name→ Este método personaliza la forma en que se muestra el nombre de un vehículo en Odoo, combinando los campos modelo y marca para generar un nombre más descriptivo.
✅ Permite asignar un usuario responsable a cada vehículo.
✅ Mejora la organización y el control sobre los vehículos.
✅ Facilita búsquedas y filtros en la interfaz de Odoo.
Con este cambio, el módulo viajes ahora permite asociar vehículos con usuarios, lo que facilita la gestión de flotas o el control de activos en Odoo. 🚗🔗👤
3. Agregar nuevo campo conductorid en el modelo Viaje #
Este cambio agrega relaciones Many2one en el modelo Viaje, permitiendo asociar un conductor (res.partner) a cada viaje.
Añade la relación al fichero:
models/viaje.py
1from odoo import models, fields, api 2from datetime import timedelta 3 4 5class Viaje(models.Model): 6 _name = 'viajes.viaje' 7 _description = "Viajes" 8 9 titulo = fields.Char(required=True) 10 11 .............. 12 13 # En la relación many2one me permite elegir un partner/cliente o crear uno directamente 14 conductor_id = fields.Many2one('res.partner', string="Conductor")
📌 ¿Qué hace?
- 🔗 Relaciona un viaje con un conductor almacenado en
res.partner. - 📝 Permite seleccionar o crear un nuevo conductor directamente en el formulario del viaje.
- 🎯 Filtra los partners para que solo aparezcan los que sean de tipo "Conductor" (esto se debe manejar en una vista o con un dominio en Odoo).
En Odoo, res.partner almacena tanto clientes como proveedores, y se puede extender para incluir conductores con un campo adicional (tipo_conductor).
4. Agregar nuevo campo vehiculoid en el modelo Viaje #
Estos cambio agregan relaciones Many2one en el modelo Viaje, permitiendo asociar un vehículo (viajes.vehiculo) a cada viaje.
Explicación del campo vehiculoid #
Añade la relación al fichero:
models/viaje.py
1from odoo import models, fields, api 2from datetime import timedelta 3 4 5class Viaje(models.Model): 6 _name = 'viajes.viaje' 7 _description = "Viajes" 8 9 titulo = fields.Char(required=True) 10 11 .............. 12 13 # En la relación many2one me permite elegir un partner/cliente o crear uno directamente 14 conductor_id = fields.Many2one('res.partner', string="Conductor") 15 16 # En la relación many2one me permite elegir un vehiculo o crear uno directamente 17 vehiculo_id = fields.Many2one('viajes.vehiculo', 18 ondelete='cascade', string="Vehiculo", required=True)
📌 ¿Qué hace?
- 🔗 Relaciona un viaje con un vehículo del modelo
viajes.vehiculo. - 📝 Permite seleccionar o crear un nuevo vehículo directamente en el formulario del viaje.
- 🔄 Si el vehículo es eliminado, todos los viajes asociados también se eliminarán (
ondelete='cascade'). - ✅ Es obligatorio (
required=True), lo que significa que un viaje siempre debe tener un vehículo asignado.
✅ Permite asignar un conductor y un vehículo a cada viaje.
✅ Mejora la organización y el control de los viajes en el sistema.
✅ Facilita búsquedas y filtrado de viajes por conductor o vehículo.
✅ Garantiza la integridad de los datos: si un vehículo se borra, los viajes asociados también se eliminan automáticamente (cascade).
Con estas mejoras, el módulo viajes en Odoo ahora permite gestionar viajes con conductores y vehículos asociados, mejorando la trazabilidad y el control. 🚗👨✈️📅
5. Añadir campo propietarioid en el formulario del vehículo #
Este cambio en la vista de formulario permite visualizar y seleccionar el propietario del vehículo dentro del módulo viajes en Odoo.
📌 Antes:
- Solo se mostraban los campos "modelo" y "marca" en la vista principal.
📌 Ahora:
- Se ha agregado el campo
propietario_id, permitiendo seleccionar el usuario propietario del vehículo dentro del formulario.
Actualiza el archivo:
views/vehiculo.xml
1<record model="ir.ui.view" id="vehiculo_form_view"> 2 <field name="name">vehiculo.form</field> 3 <field name="model">viajes.vehiculo</field> 4 <field name="arch" type="xml"> 5 <form string="Formulario de Vehiculo"> 6 <sheet> 7 <group> 8 <field name="modelo" /> 9 <field name="marca" /> 10 <field name="propietario_id"/> 11 </group> 12 <notebook> 13 <page string="Descripcion"> 14 <field name="descripcion"/> 15 </page> 16 <page string="Acerca de"> 17 Esto es un ejemplo 18 </page> 19 </notebook> 20 </sheet> 21 </form> 22 </field> 23 </record>
6. Añadir del campo propietarioid en la vista de lista de vehículos #
Este cambio en la vista de lista (list view) de vehículos permite visualizar quién es el propietario de cada vehículo, mejorando la gestión dentro del módulo viajes en Odoo.
📌 Antes:
- La vista de lista solo mostraba "Modelo" y "Marca" de cada vehículo.
📌 Ahora:
- Se ha agregado el campo
propietario_id, lo que permite visualizar quién es el propietario de cada vehículo en la lista.
Actualiza el archivo:
views/vehiculo.xml
1<record model="ir.ui.view" id="vehiculo_list_view"> 2 <field name="name">vehiculo.list</field> 3 <field name="model">viajes.vehiculo</field> 4 <field name="arch" type="xml"> 5 <list string="Vehiculo List"> 6 <field name="modelo" /> 7 <field name="marca" /> 8 <field name="propietario_id"/> 9 </list> 10 </field> 11 </record>
7. Añadir del campo vehiculoid en la vista de lista de viajes #
Este cambio en la vista de lista (list view) de viajes permite visualizar qué vehículo está asignado a cada viaje, facilitando la gestión de los viajes dentro del módulo viajes en Odoo.
📌 Antes:
- La vista de lista solo mostraba "Título", "Duración" y "Estado" de cada viaje.
📌 Ahora:
- Se ha agregado el campo
vehiculo_id, permitiendo visualizar qué vehículo está asignado a cada viaje.
Actualiza el archivo:
views/viaje.xml
1<record model="ir.ui.view" id="viaje_list_view"> 2 <field name="name">viaje.list</field> 3 <field name="model">viajes.viaje</field> 4 <field name="arch" type="xml"> 5 <list string="Viaje List"> 6 <field name="titulo" /> 7 <field name="duracion" /> 8 <field name="vehiculo_id"/> 9 <field name="estado" /> 10 </list> 11 </field> 12 </record>
8. Añadir de los cambios en la vista de formulario de Viaje #
Este cambio reorganiza la estructura del formulario de viajes en Odoo, mejorando la organización y la usabilidad.
📌 Antes:
- Todos los campos estaban en una sola sección, sin organización clara.
📌 Ahora:
- Se han creado dos grupos para organizar mejor la información:
- "General" → Contiene información clave del viaje.
- "Calendario" → Contiene información relacionada con la programación del viaje.
Grupo "General" #
- 📌
vehiculo_id→ Permite seleccionar el vehículo asignado al viaje. - 📌
titulo→ Nombre o descripción breve del viaje. - 📌
conductor_id→ Permite seleccionar un conductor para el viaje. - 📌
estado→ Estado actual del viaje (Planeado,En curso,Finalizado).
Grupo "Calendario" #
- 📌
fecha_inicio→ Fecha en la que comienza el viaje. - 📌
duracion→ Duración del viaje en días. - 📌
plazas→ Número de plazas disponibles para el viaje.
Actualiza el archivo:
views/viaje.xml
1<record model="ir.ui.view" id="viaje_form_view"> 2 <field name="name">viaje.form</field> 3 <field name="model">viajes.viaje</field> 4 <field name="arch" type="xml"> 5 <form string="Formulario de Viajes"> 6 <sheet> 7 <group> 8 <group string="General"> 9 <field name="vehiculo_id"/> 10 <field name="titulo"/> 11 <field name="conductor_id"/> 12 <field name="estado" /> 13 </group> 14 <group string="Calendario"> 15 <field name="fecha_inicio"/> 16 <field name="duracion"/> 17 <field name="plazas"/> 18 </group> 19 </group> 20 </sheet> 21 </form> 22 </field> 23 </record>
9. Actualizamos los valores demo de la aplicación #
Restructura los datos de demostración para incluir los nuevos campos y relaciones en la aplicación de viajes.
Actualiza el archivo:
demo/demo.xml
1<odoo> 2 <data> 3 <record id="vehiculo_panda" model="viajes.vehiculo"> 4 <field name="modelo">Panda</field> 5 <field name="marca">Seat</field> 6 </record> 7 <record id="vechiculo_tesla" model="viajes.vehiculo"> 8 <field name="modelo">Model S</field> 9 <field name="marca">Tesla</field> 10 </record> 11 12 </data> 13</odoo>
Actualiza el archivo:
demo/demo.viaje.xml
1<odoo> 2 <data> 3 <!-- Datos de demostración para Viajes --> 4 <record id="viaje_demo_1" model="viajes.viaje"> 5 <field name="titulo">Viaje a París</field> 6 <field name="fecha_inicio">2025-06-01</field> 7 <field name="duracion">5</field> 8 <field name="plazas">20</field> 9 <field name="estado">planeado</field> 10 <field name="vehiculo_id" ref="vehiculo_panda"/> 11 </record> 12 13 <record id="viaje_demo_2" model="viajes.viaje"> 14 <field name="titulo">Excursión a la Montaña</field> 15 <field name="fecha_inicio">2025-03-15</field> 16 <field name="duracion">2</field> 17 <field name="plazas">15</field> 18 <field name="estado">en_curso</field> 19 <field name="vehiculo_id" ref="vechiculo_tesla"/> 20 </record> 21 22 <record id="viaje_demo_3" model="viajes.viaje"> 23 <field name="titulo">Tour por la Costa</field> 24 <field name="fecha_inicio">2025-01-20</field> 25 <field name="duracion">7</field> 26 <field name="plazas">25</field> 27 <field name="estado">finalizado</field> 28 <field name="vehiculo_id" ref="vehiculo_panda"/> 29 </record> 30 </data> 31</odoo>
10. Reiniciar el módulo en Odoo y actualizar aplicación #
Reinicia el servidor odoo y actualiza la aplicación de viajes para aplicar los cambios.
11. Relacion One2many #
12. Añadir la relación One2many en el modelo Vehiculo #
El campo viaje_ids define una relación One2many en Odoo, lo que permite asociar múltiples viajes (viajes.viaje) a un solo vehículo (viajes.vehiculo).
Añade la relación viajes_ids al fichero:
models/VehiculoModel.py
1# -*- coding: utf-8 -*- 2from odoo import models, fields, api 3 4class Vehiculo(models.Model): 5 _name = 'viajes.vehiculo' 6 _description = "viajes Vehiculo" 7 modelo = fields.Char(string="Modelo", required=True) 8 marca = fields.Char(string="Marca") 9 descripcion = fields.Text() 10 11 #Con la relación many2one me permite seleccionar un usuario o crearlo directamente 12 propietario_id = fields.Many2one('res.users', 13 ondelete='set null', string="Propietario", index=True) 14 15 @api.depends('modelo', 'marca') 16 def _compute_display_name(self): 17 for record in self: 18 record.display_name = f"{record.modelo} - {record.marca}" if record.marca else record.modelo 19 20 viaje_ids = fields.One2many( 21 'viajes.viaje', 'vehiculo_id', string="Viajes del coche")
🔹 1. fields.One2many('viajes.viaje', 'vehiculo_id')
'viajes.viaje'→ Es el modelo secundario (hijos), es decir, el modelo que almacena los viajes.'vehiculo_id'→ Es el campo Many2one enviajes.viajeque referencia al vehículo.
📌 Esto significa que cada vehiculo puede tener varios viajes, pero cada viaje solo puede estar asociado a un vehiculo.
🔹 2. string="Viajes del coche"
- Este texto aparecerá en la interfaz de Odoo, identificando el campo en los formularios y vistas.
✅ Permite ver todos los viajes que ha realizado un vehículo en un solo lugar.
✅ Facilita la administración de registros en Odoo.
✅ Mejora la organización al vincular automáticamente los viajes con su respectivo vehículo.
13. Modifica el formulario de vehículo para mostrar los viajes asociados #
Este fragmento de código añade una pestaña en el formulario de Vehículos, donde se pueden ver todos los viajes asociados a un vehículo.
Actualiza el archivo:
views/vehiculo.xml
1<record model="ir.ui.view" id="vehiculo_form_view"> 2 <field name="name">vehiculo.form</field> 3 <field name="model">viajes.vehiculo</field> 4 <field name="arch" type="xml"> 5 <form string="Formulario de Vehiculo"> 6 <sheet> 7 <group> 8 <field name="modelo" /> 9 <field name="marca" /> 10 <field name="propietario_id"/> 11 </group> 12 <notebook> 13 <page string="Descripcion"> 14 <field name="descripcion"/> 15 </page> 16 <page string="Acerca de"> 17 Esto es un ejemplo 18 </page> 19 <page string="Viajes"> 20 <field name="viaje_ids"> 21 <list string="Viajes registrados"> 22 <field name="titulo"/> 23 <field name="conductor_id"/> 24 </list> 25 </field> 26 </page> 27 </notebook> 28 </sheet> 29 </form> 30 </field> 31 </record>
- ✅ Permite ver de un vistazo todos los viajes en los que se ha usado un vehículo.
- ✅ Facilita la trazabilidad de los vehículos en los viajes.
- ✅ Evita tener que buscar manualmente los viajes en el sistema.
14. Reiniciar el módulo en Odoo y actualizar aplicación #
Reinicia el servidor odoo y actualiza la aplicación de viajes para aplicar los cambios.
15. Relacion Many2many #
pasajerosids: Relación Many2many con res.partner #
📌 ¿Qué hace?
- Permite asignar múltiples pasajeros a un viaje.
- 📂 Tipo:
Many2many→ Un viaje puede tener varios pasajeros, y un pasajero puede estar en varios viajes. - 🔄
res.partner→ Usa el modelo de contactos en Odoo, lo que permite seleccionar clientes existentes o crear nuevos pasajeros.
Añade la relación pasajeros_ids al fichero:
models/ViajeModel.py
1from odoo import models, fields, api 2from datetime import timedelta 3 4 5class Viaje(models.Model): 6 _name = 'viajes.viaje' 7 _description = "Viajes" 8 9 titulo = fields.Char(required=True) 10 fecha_inicio = fields.Date(default=fields.Date.today) 11 duracion = fields.Float(digits=(6, 2), help="Duracion en días") 12 plazas = fields.Integer(string="Numero de plazas disponibles") 13 14 estado = fields.Selection( 15 selection=[ 16 ('planeado', 'Planeado'), 17 ('en_curso', 'En curso'), 18 ('finalizado', 'Finalizado') 19 ], 20 string="Estado", 21 default="planeado", 22 required=True 23 ) 24 25 # En la relación many2one me permite elegir un partner/cliente o crear uno directamente 26 conductor_id = fields.Many2one('res.partner', string="Conductor") 27 28 # En la relación many2one me permite elegir un vehiculo o crear uno directamente 29 vehiculo_id = fields.Many2one('viajes.vehiculo', 30 ondelete='cascade', string="Vehiculo", required=True) 31 32 # puedo elegir uno(partner/cliente) que ya existe o crear uno nuevo 33 pasajeros_ids = fields.Many2many('res.partner', string="Pasajeros")
🔍 ¿Cómo se verá en la interfaz?
- En el formulario de Viajes, habrá un campo de selección donde el usuario podrá elegir varios pasajeros.
- Se podrá agregar clientes existentes o crear nuevos contactos directamente desde el formulario.
Modifica la vista formulario de los viajes #
Modifica el formulario de viaje para mostrar los pasajeros asociados
Actualiza el archivo:
views/viaje.xml
1<record model="ir.ui.view" id="viaje_form_view"> 2 <field name="name">viaje.form</field> 3 <field name="model">viajes.viaje</field> 4 <field name="arch" type="xml"> 5 <form string="Formulario de Viajes"> 6 <sheet> 7 <group> 8 <group string="General"> 9 <field name="vehiculo_id"/> 10 <field name="titulo"/> 11 <field name="conductor_id"/> 12 <field name="estado" /> 13 </group> 14 <group string="Calendario"> 15 <field name="fecha_inicio"/> 16 <field name="duracion"/> 17 <field name="plazas"/> 18 </group> 19 </group> 20 <label for="pasajeros_ids"/> 21 <field name="pasajeros_ids"/> 22 </sheet> 23 </form> 24 </field> 25 </record>
16. Reiniciar el módulo en Odoo y actualizar aplicación #
Reinicia el servidor odoo y actualiza la aplicación de viajes para aplicar los cambios.
Resumen del tema
Conceptos clave #
- Relaciones Relacionales en Odoo:
Many2one: asignación de propietario (res.users), conductor (res.partner) y vehículo (viajes.vehiculo) con políticas de borrado (ondelete='set null'/'cascade').One2many: relación inversa bidireccional en el vehículo (viaje_ids = fields.One2many('viajes.viaje', 'vehiculo_id')) representada como sublista interactiva en su formulario.Many2many: asociación multidireccional (pasajeros_ids = fields.Many2many('res.partner')) con tags o listas de selección múltiple.
- Método
_compute_display_name: personalización del nombre descriptivo renderizado en campos relacionales (f"{record.modelo} - {record.marca}").
Qué debes recordar #
Las relaciones Many2one, One2many y Many2many articulan la integridad referencial y navegación cruzada entre modelos de negocio y modelos base (res.partner, res.users).