Curso odoo (Módulos)
3.1. Definición de modelos
En Odoo, un modelo representa una tabla en la base de datos y se crea como una clase de Python que hereda de models.Model. Cada modelo se encarga de definir:
- Nombre interno del modelo (por ejemplo,
my.moduleores.partner). - Campos que indican la estructura de los datos.
- Comportamientos y restricciones de negocio.
Ejemplo básico de definición de un modelo
Supongamos que queremos crear un modelo para almacenar libros en una biblioteca. Creamos un archivo en la carpeta models/ llamado library_book.py con el siguiente contenido:
1from odoo import models, fields 2 3class LibraryBook(models.Model): 4 _name = 'library.book' # Nombre interno que identifica la tabla en la BDD 5 _description = 'Library Book' 6 7 name = fields.Char(string='Title', required=True) 8 author = fields.Char(string='Author') 9 description = fields.Text(string='Description') 10 publication_date = fields.Date(string='Publication Date') 11 is_available = fields.Boolean(string='Is Available?', default=True)
_name: Define el identificador interno del modelo. Este nombre se usará para referencias en otras partes (vistas, herencia, etc.)._description: Texto que describe la finalidad del modelo.fields.X: Campos definidos con tipos específicos:Char: Texto corto.Text: Texto largo.Date: Campo de fecha.Boolean: Valor verdadero o falso.- … entre otros muchos tipos (Integer, Float, Many2one, Many2many, One2many, etc.).
Nota: Además de
models.Model, existen otras clases base comomodels.TransientModel(para wizards) ymodels.AbstractModel(para crear lógica reutilizable), pero en la mayoría de los casos empezarás conmodels.Model.
3.2. Herencia de modelos existentes
En muchos casos, querrás extender la funcionalidad de un modelo ya existente en Odoo en lugar de crear uno desde cero. Existen dos maneras principales de hacerlo:
-
Herencia por extensión:
Se utiliza cuando deseas agregar campos o métodos a un modelo ya existente.1from odoo import models, fields 2 3class LibraryBookInherit(models.Model): 4 _inherit = 'library.book' # Referenciamos el modelo que queremos heredar 5 6 isbn = fields.Char(string='ISBN') 7 copies = fields.Integer(string='Number of Copies', default=1)Aquí, seguimos trabajando sobre la misma tabla de
library.book, añadiendo nuevas columnas (isbn, copies). -
Herencia delegada (
_inherits):
Se utiliza cuando creas un nuevo modelo que “hereda” los campos y métodos de otro modelo, pero cada uno sigue teniendo su propia tabla en la base de datos. Esto es útil si necesitas unir funcionalidades de distintos modelos, pero manteniendo tablas separadas.1class NewModel(models.Model): 2 _name = 'new.model' 3 _inherits = {'library.book': 'book_id'} 4 5 book_id = fields.Many2one('library.book', ondelete='cascade') 6 additional_field = fields.Char(string='Extra Field')
En ambos casos, tu objetivo es reutilizar o ampliar la lógica existente sin duplicar código ni crear modelos que hagan lo mismo.
3.3. Métodos en el modelo
Además de los campos, un modelo puede tener métodos que contienen la lógica de negocio. Algunos métodos clave:
create(vals): Controla lo que ocurre al crear un registro nuevo.write(vals): Controla lo que pasa al escribir (actualizar) un registro existente.unlink(): Se ejecuta al eliminar un registro.- Métodos con decoradores:
@api.model: Métodos que no dependen de un registro en particular (no llevanselfligado a un registro en la base de datos).@api.depends: Se utiliza para campos calculados, indicando de qué campos depende el cálculo.@api.onchange: Permite modificar campos de un formulario en tiempo real cuando otro campo cambia.
Ejemplo de un método create
1from odoo import models, fields, api 2 3class LibraryBook(models.Model): 4 _name = 'library.book' 5 _description = 'Library Book' 6 7 name = fields.Char(string='Title', required=True) 8 author = fields.Char(string='Author') 9 10 @api.model 11 def create(self, vals): 12 # Lógica antes de crear el registro 13 if not vals.get('name'): 14 vals['name'] = 'Untitled Book' 15 16 record = super(LibraryBook, self).create(vals) 17 18 # Lógica después de crear el registro (si se requiere) 19 # ... 20 21 return record
En este ejemplo, comprobamos si en los valores (vals) no viene el título (name); si no existe, se asigna “Untitled Book”. Después, se llama a super() para que la creación real en la base de datos ocurra de manera estándar.
3.4. Búsqueda y lectura de registros
Para buscar (leer) registros en Odoo, se usan métodos como search(), browse(), read(), entre otros. Estos métodos aceptan dominios (listas de tuplas) que especifican condiciones.
Uso de search()
1# Ejemplo de dominio básico 2books = self.env['library.book'].search([('author', '=', 'Miguel de Cervantes')])
self.env['library.book']es la manera de obtener el “entorno” para realizar la búsqueda en el modelolibrary.book.- El dominio
[('author', '=', 'Miguel de Cervantes')]indica que queremos todos los libros donde el campoauthorsea exactamente “Miguel de Cervantes”. - El resultado
booksserá un recordset (conjunto de registros). Puedes iterar sobre ellos o acceder a sus campos.
Uso de browse() y read()
browse(): Carga registros de la base de datos a partir de un ID o lista de IDs, sin aplicar un dominio.1book = self.env['library.book'].browse(1) 2if book.exists(): 3 print(book.name)read(): Retorna los valores de los campos en forma de lista de diccionarios, útil para exportar datos o procesarlos sin la lógica adicional del recordset.1values = book.read(['name', 'author']) 2# values podría resultar en [{'id': 1, 'name': 'El Ingenioso Hidalgo...', 'author': 'Miguel de Cervantes'}]
Dominios y contextos
- Dominios (
domain): Sirven para filtrar la búsqueda (por ejemplo, “libros con fecha posterior a 2020”). - Contextos (
context): Se utilizan para pasar información adicional que pueda afectar el comportamiento de ciertas operaciones (por ejemplo, definir una moneda específica o un idioma).
Ejemplo:
self.with_context(lang='es_ES').search([...])para establecer un contexto de idioma antes de la búsqueda.
Conclusión de la Parte 3
- Un modelo en Odoo se define mediante una clase Python que hereda de
models.Model. - Puedes extender modelos existentes usando
_inherito_inherits. - Los métodos (
create,write,unlink, entre otros) te permiten personalizar la lógica de cómo se crean, modifican o eliminan registros. - Para buscar registros, utilizas métodos como
search(),browse(),read(), con la opción de usar dominios para filtrar y contextos para ajustar la forma en que se ejecutan las operaciones.
Con este conocimiento, estás listo para profundizar en el uso de vistas (formularios, listas, etc.) en Odoo, que será el siguiente paso lógico al crear cualquier módulo con interfaz de usuario. ¡Continuemos avanzando en el desarrollo de módulos personalizados!
- Loading...