Ir al contenido

Cómo desarrollar un módulo Odoo 19: convenciones de la comunidad

Estructura, manifest, seguridad, ORM y buenas prácticas OCA
16 de junio de 2026 por
Cómo desarrollar un módulo Odoo 19: convenciones de la comunidad
Aitor Atencia

Odoo · Desarrollo · Convenciones OCA

Aprende a crear un módulo Odoo 19 siguiendo las reglas que define la comunidad: estructura de carpetas, manifest, seguridad, ORM y buenas prácticas.

Logo Odoo
Un módulo bien estructurado es fácil de mantener, probar y compartir.

Fundamentos

¿Qué es un módulo Odoo?

Un módulo (addon) es la unidad de extensión de Odoo. Puede añadir modelos, vistas, menús, datos, informes, assets web y lógica de negocio. La comunidad OCA (Odoo Community Association) y la documentación oficial establecen convenciones que garantizan calidad y compatibilidad entre proyectos.

«Un módulo hace una cosa y la hace bien. Extiende sin modificar el núcleo.»

Estructura

Árbol de directorios recomendado

Python
Odoo está escrito en Python. Tu módulo también.
mi_modulo/
├── __manifest__.py          # Metadatos y dependencias
├── __init__.py              # Importa models/, controllers/, wizards/
├── models/
│   ├── __init__.py
│   └── mi_modelo.py
├── views/
│   └── mi_modelo_views.xml
├── security/
│   ├── ir.model.access.csv  # Permisos ACL
│   └── security.xml         # Grupos y record rules
├── data/                    # Datos XML/CSV (cron, secuencias…)
├── wizards/                 # Asistentes transitorios
├── reports/                 # Informes QWeb
├── static/src/              # JS, SCSS, XML (OWL)
├── i18n/                    # Traducciones (.po)
└── tests/                   # Tests unitarios

Manifest

El fichero __manifest__.py

Es el «DNI» del módulo. Define nombre, versión, dependencias, ficheros de datos y metadatos:

# -*- coding: utf-8 -*-
{{
    'name': 'Mi Módulo',
    'version': '19.0.1.0.0',       # Mayor.Odoo.Menor.Revisión.Patch
    'category': 'Sales',
    'summary': 'Descripción corta en una línea',
    'author': 'Tu Nombre',
    'license': 'LGPL-3',
    'depends': ['base', 'sale'],
    'data': [
        'security/ir.model.access.csv',
        'views/mi_modelo_views.xml',
    ],
    'installable': True,
    'application': False,
}}

Reglas del manifest

  • version empieza por la versión de Odoo (19.0)
  • depends lista solo módulos estrictamente necesarios
  • data: seguridad primero, menús al final
  • demo separado de data
  • Declara external_dependencies si usas librerías Python externas

Modelos

Definir modelos con el ORM

Cada modelo Python mapea a una tabla PostgreSQL. Usa _name en formato prefijo.modelo:

from odoo import api, fields, models

class MiModelo(models.Model):
    _name = 'mi.modulo'
    _description = 'Mi Modelo'

    name = fields.Char(string='Nombre', required=True)
    partner_id = fields.Many2one('res.partner', string='Cliente')
    state = fields.Selection([
        ('draft', 'Borrador'),
        ('done', 'Hecho'),
    ], default='draft')

    @api.model_create_multi
    def create(self, vals_list):
        records = super().create(vals_list)
        return records
Regla OCA / OdooPor qué
Siempre super() en create/write/unlinkRespeta herencias y triggers
@api.model_create_multi en createRendimiento en lotes (Odoo 19)
@api.depends explícito en computesEvita recálculos innecesarios
_inherit para extender, no modificar corePrincipio Open/Closed (SOLID)
Strings en inglés en código; traducciones en i18n/Estándar internacionalización

Seguridad

ACL y reglas de acceso

Seguridad
Todo modelo nuevo necesita permisos en ir.model.access.csv.

Fichero security/ir.model.access.csv:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_mi_modulo_user,mi.modulo.user,model_mi_modulo,base.group_user,1,1,1,0
access_mi_modulo_manager,mi.modulo.manager,model_mi_modulo,base.group_system,1,1,1,1
  • Restrictivo por defecto: solo los permisos necesarios
  • Record rules en security.xml para filtrar por usuario/equipo
  • Nunca sudo() en controladores web ni APIs públicas
  • Campos sensibles con groups= restrictivo en la definición del campo

Vistas

XML con convenciones de nomenclatura

<!-- views/mi_modelo_views.xml -->
<record id="view_mi_modulo_form" model="ir.ui.view">
    <field name="name">mi.modulo.form</field>
    <field name="model">mi.modulo</field>
    <field name="arch" type="xml">
        <form>
            <sheet>
                <group>
                    <field name="name"/>
                    <field name="partner_id"/>
                    <field name="state"/>
                </group>
            </sheet>
        </form>
    </field>
</record>

Convenciones de IDs XML: view_<modelo>_<tipo>, action_<modelo>, menu_<nombre>. En Odoo 17+ usa t-out en lugar de t-esc en plantillas QWeb.

Calidad

Testing y herramientas

HerramientaUso
TransactionCaseTests transaccionales con rollback
SavepointCaseTests rápidos con savepoints
black + isortFormateo automático Python
flake8 + pylint-odooLinting y reglas OCA
pre-commitHooks antes de cada commit
# tests/test_mi_modulo.py
from odoo.tests import TransactionCase

class TestMiModulo(TransactionCase):
    def test_create_record(self):
        record = self.env['mi.modulo'].create({{'name': 'Test'}})
        self.assertEqual(record.state, 'draft')

Instalación

Activar tu módulo

  1. Coloca el módulo en odoo/addons/custom/mi_modulo/
  2. Reinicia Odoo: docker compose restart odoo
  3. Actualiza lista de apps: Ajustes → Activar modo desarrollador → Actualizar lista
  4. Busca «Mi Módulo» en Aplicaciones e instala
  5. O desde terminal: make update MODULE=mi_modulo
Aplicaciones Odoo
El módulo aparece en Aplicaciones tras actualizar la lista.

Referencias

Documentación y comunidad

Resumen

Un módulo Odoo 19 bien hecho respeta la estructura de carpetas, declara dependencias mínimas, protege cada modelo con ACL, usa el ORM correctamente y incluye tests. Seguir las convenciones OCA no es burocracia: es la diferencia entre un prototipo y software mantenible.

en Odoo
Cómo instalar Odoo 19 con Docker: guía paso a paso
Docker · PostgreSQL · Nginx — entorno reproducible para desarrollo y producción