Skip to Content
मेन्यू
This question has been flagged
2 Replies
323 Views

Hi everyone,

I’m facing an issue with multiple @api.onchange methods where one onchange indirectly triggers another due to a field update inside it. This leads to unexpected behavior in domain filtering.

Let’s say I have two onchange methods:

@api.onchange('field_a') def onchange_a(self): self.domain_field = some_logic_based_on_a @api.onchange('field_b') def onchange_b(self): self.field_a = False # This triggers onchange_a again self.domain_field = some_logic_based_on_b

The problem is that when field_b changes, it updates field_a, which re-triggers onchange_a, and this overwrites the domain logic set by onchange_b.

As a result, the final domain on domain_field becomes inconsistent or incorrect, depending on which onchange executes last.


In complex forms where multiple fields influence a shared domain or selection field, this kind of chained onchange can cause:

  • Unintended overrides of previous logic.
  • Incorrect domain being applied.
  • Confusing user experience on the form.


What’s the best way to handle such cases in Odoo?

  • Is there a way to control or prevent re-triggering another onchange when setting a field inside one?
  • Any alternative way to achieve that things  
  • Any better practice to manage interdependent fields without causing these side-effects?

Thanks in advance for any advice!

Avatar
Discard
Best Answer

Hii,

Here is updated code 
from odoo import models, fields, api


class MyModel(models.Model):

    _name = 'my.model'

    _description = 'My Model'


    field_a = fields.Many2one('res.partner', string='Field A')

    field_b = fields.Many2one('res.partner.category', string='Field B')

    domain_field = fields.Many2one('product.product', string='Domain Field')


    @api.onchange('field_a', 'field_b')

    def _onchange_field_a_b(self):

        """Centralized onchange handler to avoid chained effects."""

        domain = []


        if self.field_b:

            # Priority: field_b logic

            self.field_a = False  # Reset A if B is selected

            domain = [('categ_id', '=', record.field_a.id)], limit=1)

            else:

                record.domain_field = False


    domain_field = fields.Many2one('product.product', string='Domain Field', compute='_compute_domain_field', store=True)


i hope it is usefull

Avatar
Discard
Best Answer

Hi Dishant, 
Try using computed fields for such interdependencies instead of multiple onchange functions,

@api.depends('field_a', 'field_b')
def _compute_domain_field(self):
    for record in self:
        if record.field_b:
            record.domain_field = some_logic_based_on_b
        elif record.field_a:
            record.domain_field = some_logic_based_on_a
        else:
            record.domain_field = False

domain_field = fields.Char(compute='_compute_domain_field', store=True)

@api.onchange('field_b')
def onchange_b(self):
    if self.field_b:
        self.field_a = False

Thanks

Avatar
Discard
Related Posts Replies Views Activity
3
मई 24
5306
3
अग॰ 23
6915
2
जुल॰ 22
11776
1
अग॰ 25
162
0
जुल॰ 25
454