Onchange with Compute Methods

Odoo Compute vs Onchange Methods

Odoo offers two essential mechanisms to apply dynamic logic within models: Compute Methods and Onchange Methods. Both serve different purposes but are commonly used together in business applications like quotation pricing, inventory adjustments, or order references.

What is a Compute Method?

A compute method is used to automatically calculate the value of a field based on one or more other fields. This value is not stored unless explicitly declared with store=True, and it is recalculated whenever a dependent field changes.

Example: Calculating Total Rent in a Vehicle Rental System

Let’s build a simple rental model where the total rent is calculated based on:

  • hour_rate: Rate per hour
  • hours: Number of hours
from odoo import models, fields

class VehicleRental(models.Model):
    _name = "vehicle.rental"
    _description = "Vehicle Rental"

    hour_rate = fields.Monetary(string="Hourly Rate")
    hours = fields.Integer(string="Hours")
    total_rent = fields.Monetary(string="Total Rent", compute="_compute_total_rent")

    def _compute_total_rent(self):
        for record in self:
            record.total_rent = record.hour_rate * record.hours

At this point, the total rent is computed—but not automatically updated when either field changes. To fix that, we need to add dependencies to tell Odoo when this field should be recalculated.

Using @api.depends for Compute Fields

Odoo’s ORM depends on the @api.depends() decorator to understand which fields affect a computed field.

from odoo import models, fields, api

class VehicleRental(models.Model):
    _name = "vehicle.rental"
    _description = "Vehicle Rental"

    hour_rate = fields.Monetary(string="Hourly Rate")
    hours = fields.Integer(string="Hours")
    total_rent = fields.Monetary(string="Total Rent", compute="_compute_total_rent")

    @api.depends('hour_rate', 'hours')
    def _compute_total_rent(self):
        for record in self:
            record.total_rent = record.hour_rate * record.hours

Odoo will automatically re-compute total_rent if either hour_rate or hours changes—without needing user interaction.

What is an Onchange Method?

The @api.onchange() method is triggered only in the form view when the value of a specified field is changed by the user. It’s primarily used for real-time updates in the UI, not for storing computed values in the database.

Example: Setting Reference on Vehicle Selection

Let’s update the rental model to include a reference name that dynamically updates when the user selects a vehicle.

from odoo import models, fields, api

class VehicleRental(models.Model):
    _name = "vehicle.rental"
    _description = "Vehicle Rental"

    name = fields.Char(string="Reference")
    vehicle_id = fields.Many2one('fleet.vehicle', string="Vehicle")

    @api.onchange('vehicle_id')
    def _onchange_vehicle(self):
        if self.vehicle_id:
            self.name = f"Rental Order for {self.vehicle_id.name}"

When a user picks a vehicle in the form view, the name field auto-fills with a reference like “Rental Order for Toyota Camry”. This does not store the name unless the user saves the record.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message