2 - Understanding the Odoo Module Structure
At its core, an Odoo module is simply a standard Python package with a specific directory structure and a special descriptor file. Understanding this architecture is the most important step in building scalable, maintainable applications in Odoo 19.
When Odoo starts, it scans the directories listed in your addons_path (defined in your odoo.conf). It recognizes a directory as a valid module only if it contains a __manifest__.py file.
1. The Anatomy of an Odoo Module
While Odoo allows flexibility, adhering to the official directory structure is an industry standard. A professional Odoo 19 module typically looks like this:
my_custom_module/ ├── init.py ├── manifest.py ├── controllers/ │ ├── init.py │ └── main.py ├── models/ │ ├── init.py │ └── my_model.py ├── security/ │ ├── ir.model.access.csv │ └── security.xml └── views/ ├── my_model_views.xml └── menu_views.xml
2. The Heart of the Module: __manifest__.py
The __manifest__.py file is a single Python dictionary that declares your module to the Odoo framework. It dictates the module's name, its dependencies, and the exact order in which XML and CSV data files are loaded into the database.
Here is a professional, production-ready example of a __manifest__.py file for Odoo 19:
{
'name': 'Real Estate Management',
'version': '19.0.1.0.0',
'category': 'Sales/Real Estate',
'summary': 'Manage real estate properties and client offers',
'description': """
Professional Real Estate Management Module for Odoo 19.
Features include:
- Property listings
- Buyer offer tracking
- Automated invoicing
""",
'author': 'Your Company Name',
'website': 'https://www.yourwebsite.com',
'license': 'LGPL-3',
# ANY module your module relies on must be listed here
'depends': ['base', 'mail', 'account'],
# Data files always load in the exact order listed below
'data': [
'security/security.xml',
'security/ir.model.access.csv',
'views/property_views.xml',
'views/menu_views.xml',
],
# Demo data is only loaded if the database is created with "Load demo data" checked
'demo': [
'demo/property_demo.xml',
],
'installable': True,
'application': True,
'auto_install': False,
}
3. The Python Initializer: __init__.py
Because an Odoo module is a Python package, it requires __init__.py files to tell the Python interpreter to treat the directories as modules.
In Odoo, these files are used to import the Python files containing your models and controllers so the framework can load them into memory.
The Root __init__.py (Located at my_custom_module/__init__.py): This file imports your primary Python directories.
from . import models
from . import controllers
The Models __init__.py (Located at my_custom_module/models/__init__.py): This file imports the specific Python files within the models directory.
from . import my_model
from . import another_model
4. Professional Best Practices & Advice
💡 PRO TIP: The Golden Rule of Data Loading Order The data list in your __manifest__.py is executed sequentially from top to bottom. Security files must always come first. If you try to load a view for a model before loading the ir.model.access.csv that grants permission to that model, Odoo will throw a critical error during installation.
Versioning Strategy: Use the format [Odoo Version].[Major].[Minor].[Patch]. For Odoo 19, your first version should be 19.0.1.0.0. This instantly tells other developers which Odoo version your code targets.
The application vs. installable keys: Setting 'application': True will elevate your module to appear in the main "Apps" dashboard in Odoo by default. If it is purely a technical backend fix, keep it as False so it stays hidden in the "Modules" list.
Licensing is Mandatory: Always declare a 'license'. In the Odoo ecosystem, 'LGPL-3' is the standard open-source license, while 'OPL-1' (Odoo Proprietary License) is used for paid modules you intend to sell on the Odoo App Store.
There are no comments for now.