We have stumbled upon context and domain several times. We have seen that window actions are able to set them and relational fields in models can also have them as attributes.

The context is a dictionary carrying session data that can be used on both the client-side user interface and the server-side ORM and business logic.

On the client side it can carry information from one view to next, such as the ID of the record active on the previous view, after following a link or a button, or to provide default values to be used in the next view.

On the server side, some recordset field values can depend on the locale settings provided by the context. In particular the lang key affects the value of translatable fields. Context can also provide signals for server-side code. For example, the active_test key when set to False changes the behavior of ORM's search() method so that it does not filter out inactive records.

An initial context from the web client looks like this:

{'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': 1} 

You can see the lang key with the user language, tz with the time zone information, and uid with the current user ID.

When opening a form from a link or a button in a previous view, an active_id key is added to the context, with the ID of record we were positioned at, in the origin form. In the particular case of list views, we have an active_ids context key containing a list of the record IDs selected in the previous list.

On the client side, the context can be used to set default values or activate default filters on the target view, using keys with the default_ or default_search_ prefixes. Here are some examples:

To set the current user as a default value of the user_id field, we will use the following:

{'default_user_id': uid} 

To have a filter_my_tasks filter activated by default on the target view, we will use this:

{'default_search_filter_my_tasks': 1} 

The domain is used to filter data records. They use a specific syntax that the Odoo ORM parses to produce the SQL WHERE expressions that will query the database.

A domain expression is a list of conditions. Each condition is a ('field_name', 'operator', value') tuple. For example, this is a valid domain expression, with only one condition: [('is_done','=',False)].

Following is an explanation of each of these elements:

The field name is the field being filtered, and can use dot-notation for fields in related models.

The value is evaluated as a Python expression. It can use literal values, such as numbers, Booleans, strings, or lists, and can use fields and identifiers available in the evaluation context. There are actually two possible evaluation contexts for domains:

The operator can be:

A domain expression is a list of items, and can contain several condition tuples. By default these condition will implicitly be combined using the AND logical operator. This means that it will only return records meeting all these conditions.

Explicit logic operators can also be used: the ampersand symbol, '&', for AND operations (the default), and the pipe symbol,'|', for OR operations. These will operate on the next two items, working in a recursive way. We'll look at this in more detail in a moment.

The exclamation point, '!', represents the NOT operator, is also available and operates on the next item. So, it should be placed before  the item to be negated. For example, the ['!', ('is_done','=',True)]  expression would filter all not done records.

The "next item" can also be an operator item acting on its next items, defining nested conditions. An example may help us to better understand this.

In server-side record rules, we can find domain expressions similar to this one:

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

This domain filters all the records where the current user is in the follower list, is the responsible user, or does not have a responsible user set.

The first '|' (OR) operator acts on the follower's condition plus the result of the next condition. The next condition is again the union of two other conditions: records where either the user ID is the current session user or it is not set.

The following diagram illustrates this nested operators resolution:

Domain expressions