Odoo Domain Filter Builder & Explainer

See your domain as a logic tree — the structure prefix notation hides.

match all of these

Add your first condition

Logic tree
AND
Odoo domain
[]
Advertisement

The basics

What is an Odoo domain filter?

An Odoo domain is the list of criteria the ORM uses to select records — the same mechanism behind search views, list view filters, ir.rule record rules, related-field domains in views, and any search() / search_count() call in Python or JavaScript. A domain is written as a Python list, and each item is either a logical operator or a 3-element tuple called a leaf:

(
'state' field
,
'=' operator
,
'done' value
)

Getting started

How to use this tool

Builder

Construct a domain visually: add conditions and groups, pick the field, operator and value for each, and toggle AND / OR / NOT. The logic tree and the generated Odoo domain update as you go.

Explainer

The reverse: paste an existing domain from your code and get back the logic tree plus a plain-English explanation of exactly what it matches — then open it in the Builder to tweak it.

Prefix notation

Why prefix notation is confusing

Odoo domains put logical operators before their operands: '|' takes the next two terms, '&' likewise, and '!' negates one. The logic tree above shows the grouping your code actually expresses — not the one you think it does. Conditions with no explicit operator between them are joined by an implicit AND, and the empty domain [] matches every record.

Reference

Odoo domain operators

Every comparison operator Odoo's ORM understands, and what each one means as a search condition.

=

is equal to — the default equality check, works on virtually any field type.

!=

is not equal to — the negated form of =.

>

is greater than — for numbers, dates and datetimes.

>=

is greater than or equal to.

<

is less than.

<=

is less than or equal to.

in

is in a list — matches when the field equals any item in the given list.

not in

is not in a list — matches when the field equals none of the items.

like

matches a pattern — case-sensitive, SQL-style % wildcards.

not like

does not match a pattern — the negated, case-sensitive form.

ilike

contains, case-insensitive — Odoo's most common text-search operator; wraps the value in % wildcards implicitly.

not ilike

does not contain, case-insensitive.

=like

matches an exact pattern — like a raw SQL LIKE, without Odoo's implicit wildcard wrapping.

=ilike

matches an exact pattern, case-insensitive — the case-insensitive counterpart to =like.

child_of

is a child of — matches a record and all of its descendants in a hierarchical field (e.g. product categories).

parent_of

is a parent of — matches a record and all of its ancestors in a hierarchical field.

=?

is equal to, ignored if empty — dropped from the domain entirely when the comparison value is False/None, handy for optional filters built dynamically.

Examples

Common Odoo domain examples

Real domains you can paste into the Explainer above to see them broken down.

[('state', '=', 'draft')]

records still in draft state.

['|', ('state', '=', 'draft'), ('state', '=', 'sent')]

draft OR sent — an explicit OR of two conditions.

[('user_id', '=', uid)]

"assigned to me" — uid is the current user, preserved as a raw identifier.

[('create_date', '>=', '2024-01-01'), ('amount_total', '>', 5000)]

created this year AND over a threshold — an implicit AND between two conditions.

[('state', 'not in', ['done', 'cancel'])]

exclude finished or cancelled records.

[('partner_id.country_id.code', 'in', ['US', 'CA'])]

a related-field lookup through dot notation, filtering by the partner's country.

[('category_id', 'child_of', 5)]

a category and everything nested under it.

FAQ

Frequently asked questions

What does '&' mean in an Odoo domain?

'&' is the logical AND operator. It is binary, so it combines exactly the next two terms that follow it in the domain list.

What does '|' mean in an Odoo domain?

'|' is the logical OR operator. Like '&', it is binary — it combines exactly the next two terms that follow it.

What does '!' do in an Odoo domain?

'!' is the logical NOT operator. It is unary, so it negates only the single term immediately after it.

What happens if I don't put an operator between two conditions?

Odoo joins them with an implicit AND. [('a','=',1), ('b','=',2)] means the same thing as ['&', ('a','=',1), ('b','=',2)].

What does an empty domain [] mean?

It matches every record — no filter is applied at all.

What is uid in an Odoo domain?

uid is the id of the user running the search, resolved in the domain's execution context. It's commonly used for "assigned to me" filters, e.g. [('user_id', '=', uid)].

Can I combine AND and OR in the same domain?

Yes, as long as each operator gets the operands its arity requires ('&' and '|' each take exactly two, '!' takes one). This tool's logic tree shows you exactly how your domain groups them.

What's the difference between 'like' and 'ilike'?

'like' is case-sensitive pattern matching; 'ilike' is the case-insensitive version. Both use SQL-style '%' wildcards.