Code Agency
1 min read

Writing your first Odoo module that survives an upgrade

Custom Odoo development is easy to start and easy to regret. A field guide to building modules that still work after the next major version.

Most Odoo horror stories start the same way: a quick customisation, made directly in a core module, that turns every future upgrade into surgery. The fix is discipline, not talent.

Inherit, never modify

Odoo's inheritance system exists so you never touch core code. Extend the model instead:

models/sale_order.py
from odoo import api, fields, models
 
 
class SaleOrder(models.Model):
    _inherit = "sale.order"
 
    delivery_window = fields.Selection(
        [("morning", "Morning"), ("afternoon", "Afternoon")],
        string="Delivery window",
        default="morning",
    )
 
    @api.onchange("delivery_window")
    def _onchange_delivery_window(self):
        for order in self:
            order.commitment_date = order._compute_window_date()

The same rule applies to views — inherit the XML and target elements with XPath rather than copying whole view definitions:

views/sale_order_views.xml
<record id="view_order_form_delivery" model="ir.ui.view">
  <field name="name">sale.order.form.delivery</field>
  <field name="model">sale.order</field>
  <field name="inherit_id" ref="sale.view_order_form"/>
  <field name="arch" type="xml">
    <xpath expr="//field[@name='commitment_date']" position="after">
      <field name="delivery_window"/>
    </xpath>
  </field>
</record>

Three rules we enforce on every project

  1. One purpose per module. Small modules upgrade independently; a mega-module fails as a unit.
  2. No SQL where the ORM will do. Raw queries bypass access rules and break silently between versions.
  3. Tests before the first deploy. Odoo's test framework is right there — a module without tests is a liability with a version number.

Follow those and the next major upgrade becomes a scheduled task instead of a crisis.

Get the next one in your inbox

New articles, videos and the occasional engineering note — a short mail when there’s something worth reading, nothing else.