Domain In Odoo - Odoo Tricks And Tips

Domain is used in Odoo to select records from a Model (database table) – in many different places:

  • Menus / Windows Actions
  • Form Views – to select records from a one2many or many2many
  • Record Rules
  • Filters (see below)

Create a user-defined filter

One way to understand domain is to create a new User-Defined Filter. 

The simplest way to create a filter is from the “front-end”, as explained here but this has limited functionality.

After creating it you can go to the technical menu in the “back end” (see below) or use the debug menu (both of which require you to be in “developer mode“) and make more changes.

Creating from the ‘back-end’

This example is to show orders from customers in the state of California. 

Enable “developer mode“, navigate to Technical / User-defined Filters and click on “New”:

Select a model (in this case Sale Order) and click on “Add Filter”.

Now we can select a field on sale.order. If it’s a one2many field we can select fields on the Related model (database table).

For this example, we’ll select “State” from the Invoice address

We can enter the name of the state:

[["partner_invoice_id.state_id","=","California"]]

You can copy and paste this domain and use it elsewhere.

A slightly more complex example: all products that can be purchased or sold. This uses the logical OR symbol “|” :

["|", ["purchase_ok","=",True], ["sale_ok","=",True] ]

If there were three conditions you need to have OR twice (if there are four you need three ORs, and so on).

Other logical operators are:

  • &‘ = AND (this is the default so it is optional)
  • !‘ = NOT

There are many other operators:

  • =, !=, >, >=, <, <=
  • like, not like, ilike, not ilike
  • in, not in

You can experiment with them in User-Defined Filters to get a better understanding of the syntax.

Examples

Select Purchase Orders but not RFQs:

[('state','not in',('draft','sent'))]

Multiple conditions

  • Either
    • Can be Purchased AND Can be Sold
  • OR
    • Landed Cost AND Service Type
["|", "&", ["purchase_ok","=",True], ["sale_ok","=",True], "&", ["landed_cost_ok","=",True], ["type","=","service"] ]

As explained above, the OR symbol “|” and the AND symbol “&” come before the conditions. For both of them, one symbol is followed by two conditions.

Here’s an example (from a Record Rule for Sales Order lines) which has more than two conditions:

"['&', '&', ('state', 'in', ['sale', 'done']), ('is_service', '=', True), '|', ('project_id','!=', False), ('task_id','!=', False)]"

It starts with two ANDs because there are three conditions:

  1. The SO line status is either sale or done.
  2. The SO line is for a service item (is_service =True)
  3. Either the project or task is specified

As you will see, this can become quite complex – but using Filters is a fairly easy way to try different combinations and eventually you should understand it!

Comparing with other fields

Domain can used to compare two fields rather than a field and a constant (but you cannot create filters that do this). For example, the Record Rule for “Sales / Own Documents only” uses this domain:

['|', ('user_id','=',user.id), ('user_id','=',False)]

Note that the first field name in each set is in quotes, the second one is not.

The first comparison is whether the User ID on the sales order is the current user. The second is whether there is a User ID on the sales order. So this will be true if:

  • Sales order is for the current user OR
  • Sales order has no assigned salesperson (user_id is blank)

The comparison can be with a field that is related to another Model:

[('partner_id', '=', commercial_partner_id)]

As mentioned above there are many other operators, for example:

[ '|', ('company_id', '=', False), ('company_id', 'in', company_ids)]

This will select records with no company specified (meaning they are shared) OR records for the current companies (selected in the multi-company widget as explained here)

[('type', 'not in', ['sale', 'purchase', 'cash', 'bank'])]

This will select records where the type is not any of those specified (this example is a filter on Account Journals)

A problem entering domains

Note that there are some limitations with domains if you enter them through the user interface.

In the above examples:

  • Filters use a pop-up dialog box which makes it easier to enter domains, but at the cost of limiting the functionality that is available.
  • Domains for Record Rules are entered in raw form, which is a little more difficult but allows more options.

It is possible to change the widget in the XML.

This is an extract from the XML for Automated Actions (View Name is “Automations”)

<field name="filter_pre_domain" widget="domain" options="{'model': 'model_name', 'in_dialog': True}" attrs="{'invisible': [('trigger', 'not in',['on_write','on_create_or_write'])]}"/>

The change is simple: use the char_domain widget instead

Links

Odoo ORM

Tag » Add Domain Field Odoo