As an Odoo developer often need to update field values automatically either when a user changes something in the form or when data in related fields changes. Two of the most common ways to achieve this are using @api.onchange and computed fields (@api.depends). Although both may look similar at first, they serve very different purposes. Understanding the difference between them is essential for writing clean, efficient, and bug-free Odoo code. In this guide, we'll cut through the confusion. We'll explore the core difference between computed fields and onchange, provide clear examples, and give you a simple decision matrix to use in your projects.
What is a Compute and an Onchange in Odoo?
Let's start with the most critical concept:
A Computed Field is about data logic and persistence. Its value is calculated on the server-side, typically based on other fields in the record, and can be stored in the database.
An Onchange Method is about user interface (UI) feedback. It provides immediate, client-side updates while the user is filling out a form. This method does not save data to the database automatically. Instead, it updates values temporarily in the form view, allowing users to see dynamic updates before they save the record.
Deep Dive: Computed Fields
A computed field's value is calculated by a Python method. It's part of your model's business logic.
Key Characteristics:
- Server-side: Logic executes on the Odoo server.
- Persistent: Can be stored in the database (if store=True) for efficient searching and reporting.
- ORM-integrated: Works seamlessly with searches, reads, and other ORM operations.
Example:
subtotal_price = fields.Float(compute='_compute_subtotal', store=True, string="Subtotal")
@api.depends('product_qty', 'price_unit')
def _compute_subtotal(self):
for record in self:
record.subtotal_price = record.product_qty * record.price_unit
Explanation:
Here, subtotal_price is automatically calculated whenever product_qty or price_unit changes — ensuring the subtotal always reflects the latest values. Since store=True, the computed subtotal is saved in the database, making it available for searches, filters, and reports across Odoo.

Deep Dive: Onchange Method
An onchange method is a Python method decorated with @api.onchange(). It triggers automatically when a user modifies a specific field in a form view.
Key Characteristics:
- Works only in the UI, not in backend operations or automated processes.
- Doesn’t write changes to the database until the user clicks Save.
- Commonly used for interactive UI updates, such as changing prices or setting default values dynamically.
Example:
from odoo import models, fields, api
class PurchaseOrderLine(models.Model):
_inherit = 'purchase.order.line'
is_agency_fee = fields.Boolean('Agency Fee (5%)')
agency_fee = fields.Integer('Agency Fee', store=True)
unit_price_agency_fee = fields.Float(store=True, digits='Product Price')
@api.onchange('is_agency_fee', 'agency_fee')
def _onchange_unit_price_agency_fee(self):
for line in self:
if line.is_agency_fee and line.agency_fee:
line.unit_price_agency_fee = line.price_unit * (1 + (agency_fee/100))
else:
line.unit_price_agency_fee = line.price_unit
Explanation:
Here, the @api.onchange method updates unit_price_agency_fee dynamically in the form view whenever is_agency_fee or agency_fee is changed by the user. If the “Agency Fee” checkbox is checked, the system recalculates the price by adding that percentage to the base price_unit. Because it uses @api.onchange, this calculation happens instantly in the UI but is not saved to the database until the user clicks Save, making it ideal for real-time form updates.

🔎 Onchange vs Compute : What’s the Difference?
| Feature | @api.onchange | @api.depends (Compute Field) |
| Trigger | When user changes a field in the form view | When specified dependent fields change (UI or backend) |
| Database Storage | No (temporary, UI only) | Optional (store=True saves to DB) |
| Scope | UI only | Works in both UI and backend |
| Use Case | Form interactivity, default values, dynamic UI changes | Automatic calculations, reports, and backend consistency |
| Performance | Lightweight, doesn’t hit DB | Slightly heavier, especially when stored |
| Example | Update a field when another changes on form | Recalculate total when related values change |
💡 When to Use Each
Use @api.onchange when you need real-time updates in the form view without saving to the database. Example: updating dependent dropdowns, calculating temporary totals, or pre-filling fields before saving.
Use @api.depends (computed fields) when you need consistent, reliable calculations that persist across the entire system. Example: recalculating line totals, profit margins, or stock values whenever related data changes.
Conclusion
Both @api.onchange and computed fields (@api.depends) are powerful tools for Odoo 17 developers. The key is knowing when to use each:
- onchange: interactive and temporary (UI-only)
- compute: systematic and permanent (system-wide)
By understanding this distinction, you will write more robust, reliable, and user-friendly Odoo applications. Your data layer will be solid, and your forms will be a joy to use.
