Odoo Domain Filter Builder & Explainer
See your domain as a logic tree — the structure prefix notation hides.
Add your first condition
[]
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:
Getting started
How to use this tool
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.
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.