How to Implement @api.onchange vs @api.depends in Odoo?
✅ Core Difference
Feature | @api.onchange | @api.depends |
Purpose | Trigger logic when a field changes in UI | Recalculate a computed field when dependencies change |
Execution Context | Client-side only (form view) | Server-side (ORM, UI, batch, imports, API, etc.) |
Field Storage | Doesn’t affect stored fields unless manually written | Used with @compute, which can be stored or not |
Usage Scenario | Interactive UI feedback (set values, warnings) | Auto-updated computed fields |
📌 Real Use Case: Product-Based Discount
Using @api.onchange
@api.onchange('product_id')
def _onchange_product_id(self):
if self.product_id and self.product_id.list_price > 1000:
self.discount = 10
- Triggered only when the product is changed in the form view.
- Ideal for quick UI updates (e.g., applying a discount).
Using @api.depends with @compute
discount = fields.Float(compute='_compute_discount', store=True)
@api.depends('product_id')
def _compute_discount(self):
for line in self:
line.discount = 10 if line.product_id.list_price > 1000 else 0
- Automatically computed when the product_id changes.
- Works on all levels: UI, server, API, scheduled jobs, import, etc.
⚙️ When to Use What?
Use Case | Use @api.onchange | Use @api.depends |
Form view interaction (set fields, warnings) | ✅ Yes | ❌ No |
Dynamic computed field (stored or not) | ❌ No | ✅ Yes |
Runs during data import / cron / API | ❌ No | ✅ Yes |
Temporary visual feedback | ✅ Yes | ❌ No |
Server-side data consistency | ❌ No | ✅ Yes |
⚠️ Important Notes
- @api.onchange does not persist unless explicitly written via self.field = value.
- @api.depends automatically recalculates and is part of the ORM lifecycle.
- Avoid mixing both on the same logic unless there's a specific reason.
✅ Summary Table
Decorator | Trigger Context | Works in Backend | Works in UI | Suitable For | Stores Field? |
@api.onchange | UI only | ❌ No | ✅ Yes | Form feedback, quick set | ❌ No (manual) |
@api.depends | ORM full stack | ✅ Yes | ✅ Yes | Auto-calculating fields | ✅ Yes/No |