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)
One way to see how it works is to create a new User-Defined Filter.
- e.g. We want to see orders from customers in California.
Enable “developer mode” and 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:
You can copy and paste this 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.
Select Purchase Orders but not RFQs:
- Can be Purchased AND Can be Sold
- 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 can be 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),
It starts with two ANDs because there are three conditions:
- The SO line status is either
- The SO line is for a service item (
- 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
In Record Rules and elsewhere, domain is used to compare two fields rather than a field and a constant. For example, the Record Rule for “Sales / Own Documents only”:
Note that the first field name 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 in 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)
[('type', 'not in', ['sale', 'purchase', 'cash', 'bank'])]