Apply Dynamic Domain for Relational Fields in Odoo 17

HARSHAD
May 13, 2024
dynamic-domain-relational-field-in-odoo

Setting a domain for a relational field based on another field in a single model becomes significant in several Odoo 17 cases. This allows records to be automatically sorted based on established standards. Dynamic domains based only on co-model fields have their uses, but they might not be enough in all situations. This post explores various methods for adding dynamic domains to the Odoo 17 relational fields, allowing you to customize your application to meet certain requirements.

Method 1: Defining an Onchange Function

Creating a change function that returns the domain based on the value of a particular field is one method to apply a dynamic domain. To better understand this

strategy, let’s look at an example.

class EmployeeWing(models.Model):

_name = 'employee.wing'
_description = 'Employee Wing'
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')


Let’s discuss the need to set up a user filter in this case, depending on the ‘Department Members Only’ field. The ‘Members’ field should limit selections to staff members of the specified department when ‘Department Members Only’ is set to true. Conversely, if it is false, every employee needs to be open for selection.

We can set up a change function in the Python file to achieve this:


@api.on change('pick_from_dept')

def get_employees(self):

    if self.pick_from_dept:

        domain = [('department_id', '=', self.department_id.id)]

    else:

        domain = []     return {'domain': {'member_ids': domain}}

We evaluate the value of the “pick_from_dept” property via the change function. If it is, we set up the domain to use the selected department as a filter for the “member_ids” column. In the case that it is false, we set an empty domain, making each worker open for selection.

Method 2: Defining Domain Attributes in XML

Applying an evolving topic in this manner additionally includes directly stating domain attributes in the XML file. When you wish to filter records depending on the values of a certain field, this method is quite helpful.
Let’s look at an example where we have to select a leader from among the members that have been chosen in the “member_ids” field. The “leader_id” field in the XML file has a domain property that we may define in addition to using the on-change function to return the domain:

<field name="leader_id" domain="[('id', 'in', member_ids)]"/>

The “leader_id” field can be filtered depending on the members that have been chosen by providing the domain attribute in the XML file. This guarantees that leaders can only be chosen from among the chosen members.

Method 3: Computing Possible Values for a Many2many Field

In some circumstances, you might have to apply a domain based on a many2many field and calculate its possible values. When you wish to filter records based on a related field that is not changeable in the form, this method can be helpful.

Let’s investigate a connected area for the accountable party, namely the department manager. Let’s say we need a backup for the responsible position. This backup could be the responsible person’s manager or coach. We are unable to use the on-change function to apply this domain since the responsible person field is not editable.
We can apply a domain based on the ‘alternate_id’ column and compute possible values for it to remedy this. At first, we added a new many2many column in the Py file named “alternate_id

alternate_ids = fields.Many2many('hr.employee', 'wing_alternate_rel', compute='compute_alternate_ids')

@api.depends('responsible_person_id')
def compute_alternate_ids(self):
for rec in self:
rec.alternate_ids = False
if rec.responsible_person_id:
if rec.responsible_person_id.parent_id and rec.responsible_person_id.coach_id:
rec.alternate_ids = (rec.responsible_person_id.parent_id.id, rec.responsible_person_id.coach_id.id)

In the following scenario, we compute the different values for the “alternate_ids” field using the manager and coach entries of the responsible person. If the manager and coach’s IDs are true, we set the “alternate_ids” column to include their respective IDs.


After that, given the values obtained, the domain is assigned to the “alternate_id” field in the XML file:
<field name="alternate_id" domain="[('id', 'in', alternate_ids)]"/>

<field name="alternate_ids" invisible="1"/>

When the “alternate_ids” field has been set to invisible, it remains useful for computing domain names even when it is hidden from the form view.

Using dynamic domains for relational fields in Odoo 17 is necessary to filter records according to particular criteria. You can get the needed flexibility and customization in your Odoo applications by using techniques like implementing a change function, specifying domain characteristics in XML, and determining possible values for many fields. Try out these techniques to develop strong, dynamic applications that satisfy your business needs.
Recall that utilizing Odoo’s robust ORM and comprehending the links between fields is essential for implementing dynamic domains properly. By using these methods, you may create reliable apps that offer a flawless user experience and the exact features your users require.
So proceed, investigate the opportunities presented by dynamic domains in Odoo 17, and submit your applications. the next level

"Unlock the Full Potential of Your Business with Odoo ERP!"

"Get a Cost Estimate for Your ERP Project, Absolutely FREE!"

Get a Free Quote

Leave a Reply

Your email address will not be published. Required fields are marked *