Relational fields (Many2one, One2many, Many2many) in Odoo, we often need to restrict the available records dynamically based on the values of other fields. This helps ensure only relevant records are selectable, improving UX and data accuracy. With improvements and deprecations in recent versions, there are some changes. This blog will cover how to apply dynamic domains in relational fields with Odoo 19.
Take a look at this example.
Defining a model:
class DynamicFilter(models.Model):
_name = 'dynamic.filter'
_description = 'Sample Model'
_inherit = ['mail.thread', 'mail.activity.mixin']
department_id = fields.Many2one('hr.department', string='Department')
responsible_person_id= fields.Many2one('hr.employee', related='department_id.manager_id')
pick_from_dept = fields.Boolean('Dept Members Only')
member_ids = fields.Many2many('hr.employee', string='Members')
leader_id = fields.Many2one('hr.employee')
alternate_id = fields.Many2one('hr.employee')
And the form view is defined as:
<record id="dynamic_filter_view_form" model="ir.ui.view">
<field name="name">dynamic.filter.view.form</field>
<field name="model">dynamic.filter</field>
<field name="arch" type="xml">
<form string="Sample">
<sheet>
<group>
<field name="department_id"/>
<fieldname="responsible_person_id"/>
<field name="pick_from_dept"/>
<field name="member_ids"/>
<field name="leader_id"/>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
Methods to apply dynamic domains
1. Domain attribute in XML view.
We can define a domain attribute for the relational field in the XML file. In this example, we choose the leader field based on the members, which is many2many field.
<field name="leader_id" domain="[('id', 'in', member_ids)]"/>
2. Compute method for many2many field.
We can compute and get the possible value for the many2many field, and then we can apply the domain based on that field.
The Python file looks like:
@api.depends('responsible_person_id')
def compute_alternate_ids(self):
for rec in self:
person = rec.responsible_person_id
if person and person.parent_id and person.coach_id:
rec.alternate_ids = [(6, 0, [person.parent_id.id, person.coach_id.id])]
else:
rec.alternate_ids = False
XML file:
<field name="alternate_id" domain="[('id', 'in', alternate_ids)]"/>
<field name="alternate_ids"/>
Here, depending on the responsible person, an alternate person is set such that either the manager or the coach of the responsible person. It works even if the relational field is not editable.
Dynamic domains in Odoo19 are powerful for making the relational fields more responsive and accurate. By using combinations of XML domain attributes and computed fields, we can restrict the choices available in relational fields based on other field values.
To read more about How to Apply Dynamic Domain for Relational Fields in Odoo 18, refer to our blog How to Apply Dynamic Domain for Relational Fields in Odoo 18.