Enable Dark Mode!
how-to-apply-dynamic-domain-for-relational-fields-in-odoo-18.jpg
By: Nihala KP

How to Apply Dynamic Domain for Relational Fields in Odoo 18

Technical Odoo 18

In Odoo 18, there are situations where it's necessary to set a domain on a relational field based on another field within the same model. This allows for dynamically filtering records according to certain conditions. Although static domains using only comodel fields can be useful, they might not always be enough. This article explores various ways to implement dynamic domains in Odoo 18, providing the flexibility to customize your application to meet specific requirements.

Defining a Model :

from odoo import api, fields, models
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')
    alternate_ids = fields.Many2many('hr.employee', 'wing_alternate_rel',compute='compute_alternate_ids')

Method 1: Setting Domain Attributes Directly in XML

The form view can be set up as follows:

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id="wing_form_view" model="ir.ui.view">
        <field name="name">employee.wing.form</field>
        <field name="model">employee.wing</field>
        <field name="arch" type="xml">
            <form>
                <sheet>`
                    <group>
                        <field name="department_id"/>
                        <field name="responsible_person_id"/>
                        <field name="pick_from_dept"/>
                        <field name="member_ids" widget="many2many_tags"/>
                        <field name="leader_id"/>
                        <field name="alternate_id"
                               domain="[('id', 'in', alternate_ids)]"/>
                        <field name="alternate_ids" invisible="1"/>
                    </group>
                </sheet>
            </form>
        </field>
    </record>
    <record id="action_employee_wing" model="ir.actions.act_window">
        <field name="name">Employee Wing</field>
        <field name="res_model">employee.wing</field>
        <field name="view_mode">list,form</field>
    </record>
    <menuitem id="employee_wing" parent="hr.menu_hr_employee_payroll"
              action="action_employee_wing"/>
</odoo>

To implement a dynamic domain is by specifying domain attributes directly in the XML file. This is especially helpful when you need to filter records based on the value of a particular field.

For example, we can also set the domain attribute for the "leader_id" field directly in the XML file:

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

By setting the domain attribute in the XML file, we can limit the options in the "leader_id" field to only the selected members. This ensures that only those members can be chosen as leaders.

Method 2: Computing Options for a Many2many Field

In some situations, you may need to calculate the available values for a many2many field and apply a domain based on that field. This is helpful when you want to filter records related to a field that cannot be edited directly in the form.

For example, consider the responsible person field, which links to the department manager. If we need to choose an alternate person for the responsible role, this could either be the manager or the coach of the responsible person. Since the responsible person field is not editable, applying a domain using the onchange function is not possible.

To solve this, we can compute the possible values for the 'alternate_id' field and set a domain accordingly. First, we introduce a new many2many field called 'alternate_ids' in the Python file:

    @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 this example, we compute the values for the "alternate_ids" field based on the manager and coach of the responsible person. If both the manager and coach are available, their respective IDs are added to the "alternate_ids" field.

Then, in the XML file, we apply a domain to the "alternate_id" field, filtering the options based on the computed values:

<field name="alternate_id" domain="[('id', 'in', alternate_ids)]"/>
<field name="alternate_ids" invisible="1"/>

By marking the "alternate_ids" field as invisible, we can hide it from the form view while still enabling it to be used for domain calculation.

Conclusion

In Odoo 18, applying dynamic domains to relational fields is crucial for filtering records based on specific criteria. By using methods such as setting domain attributes in XML, and calculating values for many2many fields, you can achieve greater flexibility and customization in your Odoo applications. Experiment with these techniques to build dynamic and powerful applications that align with your business needs.

The key to effectively using dynamic domains lies in understanding the relationships between fields and utilizing Odoo’s robust ORM capabilities. With these methods, you can create applications that offer a smooth user experience and deliver the exact functionality your users require.

Explore the potential of dynamic domains in Odoo 18 and elevate your applications to new heights!

To read more about How to Apply Dynamic Domain for Relational Fields in Odoo 17, refer to our blog How to Apply Dynamic Domain for Relational Fields in Odoo 17.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



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