Odoo Custom Module Development: Practices That Last
How to build Odoo custom modules that survive upgrades: inheritance, module structure, security, testing, performance and code review practices.
Odoo makes it easy to customise. That's the problem. A developer can add a field, override a method and patch a view in an afternoon. Do that fifty times without discipline and you end up with a system nobody can upgrade.
Here's how we build Odoo modules so they're still maintainable three versions later.
Rule 1: Extend, never edit
Never edit files in Odoo's core or in third-party modules. Create your own module and use inheritance:
from odoo import api, fields, models
class SaleOrder(models.Model):
_inherit = "sale.order"
delivery_window = fields.Selection(
[("am", "Morning"), ("pm", "Afternoon")],
string="Delivery window",
)
@api.constrains("delivery_window", "commitment_date")
def _check_delivery_window(self):
for order in self:
if order.delivery_window and not order.commitment_date:
raise models.ValidationError(
"Set a delivery date before choosing a delivery window."
)
Views get the same treatment, with XPath to add or move elements rather than replacing whole views.
Rule 2: Call super, almost always
When overriding a method, call super() and add behaviour before or after it. Replacing a standard method entirely means you silently lose every fix Odoo makes to it.
Rule 3: Small modules with one purpose
sale_delivery_window is better than company_customisations. Small modules are easier to test, port, disable and explain. Name them by what they do.
Rule 4: Structure consistently
sale_delivery_window/
__init__.py
__manifest__.py
models/
views/
security/ir.model.access.csv
data/
tests/
README.rst
Every module gets a README saying what it does, why it exists and who asked for it.
Rule 5: Security from the start
- Access rights (
ir.model.access.csv) for every new model - Record rules where users should see only some records
- Never use
sudo()to get around a permission problem without understanding it - Validate input in controllers, especially public ones
Rule 6: Mind performance
- Avoid database queries inside loops. Use
read_group,search_reador batch operations. - Store computed fields only when you need to search or group by them
- Add indexes on fields you search frequently
- Use background jobs for heavy work, not request-time processing
Rule 7: Write tests
At minimum, test the business rule your module introduces. Odoo's test framework runs tests on install. Run them in CI on every commit.
Rule 8: Version control and review
- Every module in Git, with a branch per feature
- Code review before merging
- Pre-commit hooks for formatting and linting (the OCA's configuration is a good starting point)
- Deploy to staging, test, then production
Rule 9: Keep a customisation register
A simple table: module, purpose, requester, date, which standard behaviour it changes. It makes upgrades and audits much easier.
When not to write a module
- Standard configuration can do it
- A process change would remove the need
- Studio can handle it (on Enterprise), for simple fields and views
- A well-maintained OCA module already does it
See Odoo Studio vs custom development for where that line falls. Our Odoo development team follows these practices on every project.
Frequently asked questions
What language are Odoo modules written in?
Python for models and business logic, XML for views and data, and JavaScript (the OWL framework) for front-end components.
Should we edit Odoo's core code?
No. Always extend through separate modules using inheritance. Core edits are lost or conflict at every update.
ERP Builders Architecture Group
The engineers responsible for integration design, data migration tooling and performance work across ERP Builders projects.
Related articles
Odoo 20 Access Rights: Migrating to ir.access
Odoo 20 removes record rules and merges them into access rights with domains. What changed, how to migrate ir.model.access.csv and ir.rule, and what to test.
Odoo Studio vs Custom Code: Where to Draw the Line
What Odoo Studio does well, where it creates trouble, and when to switch to custom module development. A practical decision guide with examples.
3D Warehouse Management: Visualising Stock in 3D
What 3D warehouse management offers: bin occupancy views, slotting decisions, space planning, and how to build a 3D view on ERP location data.
Next step
Turn the plan into a working system.
Book a consultation with an ERP consultant. No sales script — just an honest look at your situation.