Enable Dark Mode!
overview-of-context-based-domains-in-odoo19.jpg
By: Abhijith CK

Overview of Context-Based Domains in Odoo 19

Odoo 19 Technical Odoo Community Odoo Enterprises

In Odoo 19, a domain is the standard way that filters which records are visible or selectable on a field, but a static domain cannot adapt itself to the situation the user is currently in. A context-based domain solves this by reading values out of the context dictionary at the moment the view is rendered, so the same field can display different sets of records depending on where it is opened from.

A context based domain in Odoo 19 is made up of three components: an XML component that passes the required values into the context, a domain expression that reads those values back out, and a Python component that supplies the computed or related fields the domain depends on.

Syntax in XML Views

In Odoo 19, you'll often define context based domains directly inside XML views, especially on relational fields like Many2one, One2many, and Many2many. The domain attribute supports Python-like expressions that are evaluated against the context.

<field name="product_id"
       domain="[('categ_id', '=', context.get('categ_id'))]"/>

Here, when a user opens the form, the available products are filtered to match the category passed in the context. If no category is set, the domain returns all products (because False typically matches nothing in equality, so you may need to handle that case explicitly).

A more robust version:

<field name="product_id"
       domain="[('categ_id', '=', context.get('categ_id', False))] if context.get('categ_id') else []"/>

This way, the filter only applies when there's a meaningful value in the context.

1. Passing Values Through the Context

The context dictionary is the channel through which a parent view tells a field what it should filter by. Any key added to context on a field, button, or action becomes available to that field's domain, and to any view it opens.

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <record id="project_task_form_context_domain" model="ir.ui.view">
        <field name="name">project.task.form.context.domain</field>
        <field name="model">project.task</field>
        <field name="inherit_id" ref="project.view_task_form2"/>
        <field name="arch" type="xml">
            <field name="user_ids" position="attributes">
                <attribute name="context">{'task_project_id': project_id}</attribute>
                <attribute name="domain">[('id', 'in', allowed_user_ids)]</attribute>
            </field>
        </field>
    </record>
</odoo>

context attribute: Adds task_project_id to the context, set to the current value of the project_id field on the form. This makes the active project available to anything reading the context, including server-side default logic.

domain attribute: Reads allowed_user_ids, a field on the record itself, rather than reading context directly. In Odoo 19, the domain on a field is evaluated against the record, so the context is used to compute that field instead of being referenced inline.

2. The Domain Expression

Because a field's domain attribute is evaluated against fields on the current record, the cleanest pattern is to expose a computed field that already represents "the records this domain should allow," and to point the domain at that computed field. The compute method is the part that actually reacts to the context.

allowed_user_ids = fields.Many2many(
    'res.users',
    compute='_compute_allowed_user_ids',
)
@api.depends('project_id', 'project_id.user_id')
def _compute_allowed_user_ids(self):
    for task in self:
        project = task.project_id or self.env.context.get('task_project_id')
        if project:
            if not hasattr(project, 'id'):
                project = self.env['project.project'].browse(project)
            task.allowed_user_ids = project.user_id
        else:
            task.allowed_user_ids = self.env['res.users'].search([])

self.env.context.get('default_project_id'): Fallback to the context key Odoo will use when creating a task from the projects' Kanban view so that our domain expression also works for a new, unsaved task without any project_id.

allowed_user_ids: This field is not persisted and is not displayed on the form. Its only purpose is to have an entity that the domain attribute can reference to keep the domain expression clear and syntax-free.

3. Reading Context Directly in a Domain

In some simpler scenarios where the filter condition value itself exists as a field of the record instead of being calculated, it is possible to use context keys in the domain by utilizing the context_today function together with the bracket key syntax provided by the domain DSL.

<field name="partner_id"
       domain="[('company_id', 'in', [company_id, False])]"
       context="{'search_default_company_id': company_id}"/>

To use this as context, we need the filter  โ€˜company_idโ€™ in res.partner model

company_id inside domain: This refers to the company_id field, which exists on the current record and not within the context. Odoo 19 uses the record's namespace to evaluate fields in domain conditions, and hence, field references can be done without any special prefix.

search_default_company_id: A context key recognized by the search view of the Many2one Search More popup. If a corresponding search filter or searchable field exists, Odoo applies it as a default search filter, pre-filtering the records displayed instead of restricting them through the field's domain.

Domains based on context allow the same field definition to work in different ways depending on where and how the field opens, but without replicating the field in multiple views. This Odoo 19 approach emphasizes the idea of passing parameters via the context to the compute method and then directing the domain to the generated field. The benefit of this approach is that the viewโ€™s arch will remain declarative while all of the complex logic remains in Python, making testing and extending it easier. Once the approach is clear, it can be applied to any relations.

To read more about Overview of Context in Domain Odoo19, refer to our blog Overview of Context in Domain Odoo19.


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



0
Comments



Leave a comment



WhatsApp