In real-world business logic, certain field values must be derived
automatically based on other fields in the same or related records.
Computed fields in Odoo 18 provide a powerful solution for such
cases. These fields are not manually inputted; instead, their values
are dynamically calculated through functions defined in the model.
A computed field is declared in a similar way to regular fields, with
one additional argument: the compute attribute, which points to the
function that will calculate the field’s value.
from odoo import models, fields, api
class YourModel(models.Model):
_name = 'your.model'
total = fields.Float(string="Total", compute="_compute_total")
@api.depends('some_field')
def _compute_total(self):
for rec in self:
rec.total = rec.some_field * 2 # Example computation
The function _compute_total performs the actual calculation. Computed
fields, by default, are not stored, not writable, and not
searchable, unless you explicitly configure them to be.
Dependencies
To ensure the compute method runs only when necessary, you must
declare field dependencies using the @api.depends() decorator. This
tells Odoo which fields to monitor for changes that should trigger
recomputation.
Example:
from odoo import models, fields, api
class YourModel(models.Model):
_name = 'your.model'
amount = fields.Float(string='Amount')
total = fields.Float(string='Total', compute="_compute_total")
@api.depends('amount')
def _compute_total(self):
for rec in self:
rec.total = 2.0 * rec.amount
When the amount field changes, _compute_total() is automatically
triggered to update the total field.
Storing Computed Fields
By default, computed fields are not stored in the database; they are
calculated on the fly. If you want the value to be saved in the
database, use the store=True attribute.
from odoo import models, fields, api
class YourModel(models.Model):
_name = 'your.model'
amount = fields.Float(string='Amount')
total = fields.Float(string='Total', compute="_compute_total", store=True)
@api.depends('amount')
def _compute_total(self):
for rec in self:
rec.total = 2.0 * rec.amount
This makes the computed field behave like a regular stored
field—allowing you to search on it, filter it, or export it without
runtime recalculation. Odoo’s ORM ensures that stored values are
updated automatically when any of the dependencies change.
Inverse Function
Since computed fields are read-only by default, users cannot modify
them manually. However, there may be situations where you want to
allow the user to set a value for a computed field, and then update
related fields accordingly. This is done using an inverse method.
from odoo import models, fields, api
class YourModel(models.Model):
_name = 'your.model'
amount = fields.Float(string="Amount")
total = fields.Float(string='Total', compute="_compute_total", inverse="_inverse_total")
@api.depends("amount")
def _compute_total(self):
for record in self:
record.total = 2.0 * record.amount
def _inverse_total(self):
for record in self:
record.amount = record.total / 2.0
- The compute method calculates the value based
on amount.
- The inverse method allows users to enter a
value in total, and then automatically updates the amount.
The inverse function is triggered when the record is saved, while the
compute function is triggered when any of its dependencies change.