Если вы работали с настройками Odoo, наверняка встречали выражения доменов — те самые условия в квадратных скобках, которые фильтруют записи. Они живут в кнопках действий, правилах автоматизации, правилах доступа и шаблонах писем. Меньше кто знает, что в ORM Odoo есть специальный тип поля — Domain, созданный для хранения таких выражений как структурированных данных с валидацией и пользовательским интерфейсом.
Понимание поля Domain важно и разработчикам, и администраторам: кто-то пишет модули, кто-то настраивает автоматизацию. В этой заметке я объясню, что именно хранит поле Domain, как его применять на практике, как добавить в модуль или форму и каких ошибок лучше избегать.
Что такое поле Domain в Odoo
В Odoo «домен» — это список условий, по которому система выбирает записи. Это не простая строка: это набор кортежей и логических операторов, который при исполнении преобразуется в SQL WHERE, ограничивая результаты запроса.
Пример домена
[('customer_rank', '>', 0), ('active', '=', True)]
Именно это означает: вернуть записи, где customer_rank больше 0 И поле active истинно.
Поле Domain (fields.Domain) — специальный тип в ORM Odoo, предназначенный для хранения таких выражений в виде данных записи. В отличие от обычного Char, оно выполняет валидацию и предоставляет виджет, позволяющий настраивать фильтры визуально, без ручного набора синтаксиса.
Как это выглядит в интерфейсе
В интерфейсе Odoo поле Domain рендерится через виджет редактора доменов. Это визуальный конструктор: выбираете поле модели, оператор (равно, содержит, больше и т.д.) и значение. Тот же самый интерфейс используется при настройке правил доступа и автоматических триггеров.
В базе данных домены хранятся как текст — строковое представление Python-списка. Поле само сериализует и валидирует значение, так что в Python вы оперируете уже корректной доменной строкой, а слой хранения заботится о сохранении.
Это часть общей идеи модели данных Odoo: поле — не просто контейнер для байтов. Оно несёт семантику, поведение в UI и логику валидации в одном определении.
Как это поле работает
Взаимодействие с ORM и оценка домена
Что происходит под капотом
При сохранении домен записывается в виде сериализованной строки. Если в домене есть специальные переменные вроде uid, они не подставляются заранее — разрешение таких значений происходит в момент выполнения запроса, что позволяет делать фильтры динамическими и переносимыми между базами.
Odoo берёт эту строку, безопасно её оценивает и превращает в SQL WHERE. Оценка идёт через safe_eval, который поддерживает ограниченное множество Python-выражений и умеет работать с Odoo‑контекстом.
Виджет редактора доменов
По умолчанию поля типа fields.Domain отображаются виджетом domain. Через него пользователи добавляют условия, комбинируют их с помощью AND/OR и сразу видят, как это повлияет на выборку — всё без ручной работы со списками кортежей.
Именно виджет делает домены доступными для бизнес‑пользователей: не нужно знать синтаксис доменов, достаточно собрать правила в визуальном конструкторе.
Контекст модели
Поле Domain можно привязать к конкретной модели через атрибут model_field. Это подсказывает виджету, какие поля предлагать в конструкторе. Если привязки нет, вместо удобного редактора отобразится простое текстовое поле — гораздо менее удобно для конечного пользователя.
Эта привязка — часть архитектуры Odoo: поле знает, к какой модели относится, и интерфейс подстраивается под это знание.
Взаимодействие с другими записями
Domain‑поля часто используются совместно с реляционными полями: они ограничивают выбор в Many2one, определяют объём для автоматических действий или задают рамки отчётов. Поскольку фильтр применяется на уровне ORM, он учитывает права доступа и правила видимости.
Бизнес-кейсы применения
Где это реально пригодится — несколько примеров
1. Автоматизация и триггеры по почте
При настройке автоматического действия вы задаёте домен, указывающий, какие записи должны запускать действие. Например, письмо о просрочке может отправляться только для выставленных, неоплаченных счетов с прошедшим сроком. Такой домен хранится в поле filter_domain модели base.automation и активирует действие лишь для подходящих записей.
2. Правила доступа и record rules
Record rules в Odoo используют домены, чтобы ограничить, какие записи видит или редактирует группа пользователей. Правило для команды продаж может показывать только те сделки, которые назначены на её участников — проверка идёт в момент запроса, без дополнительного кода.
3. Складская логика и фильтрация операций
В управлении запасами домены помогают выбирать продукты по категории, местоположению или уровню остатков. Правило автозаказа может применять фильтр только к товарным позициям с количеством меньше порога, чтобы не запускать обработку по тысячам записей.
4. CRM — воронка и квалификация лидов
В CRM автоматизация по стадиям, правила активности и распределение лидов зависят от доменов. Правила назначения могут подбирать продавца по стране, отрасли или объёму сделки — и всё это настраивается из интерфейса благодаря полю Domain, без правки кода.
5. Динамические Many2one‑выпадающие списки
На формах домен на Many2one ограничивает, какие записи показываются в выпадающем списке. Например, показать только активных поставщиков с ненулёвым рангом — удобство для пользователя и меньше ошибок ввода. Домены могут ссылаться на другие поля формы и менять доступные опции динамически.
Создание и настройка поля
Два пути работы с Domain: безкодовое через Studio и кодовые доработки в модуле.
Через Odoo Studio
В Studio нет отдельной визуальной опции «поставить поле Domain» в конструкторе полей, но чаще всего в этом нет нужды. Встроенные редакторы доменов в автоматизациях и правилах уже дают удобный интерфейс без создания кастомного поля.
Чтобы поставить фильтр на поле Many2one в Studio, достаточно открыть свойства поля и прописать домен. Studio проверит синтаксис и сохранит выражение в определении вида.
Техническая настройка через Python
В собственном модуле добавить Domain‑поле — простая задача, это стандартная часть руководства по разработке Odoo.
Пример определения поля в модуле:
from odoo import models, fields
class MyModel(models.Model):
_name = 'my.model'
model_name = fields.Char(default='res.partner')
filter_domain = fields.Domain(
string='Filter Domain',
model_field='model_name',
help='Domain expression to filter partner records'
)
А как показать виджет на форме
В представлении формы надо ссылаться и на поле‑модель, и на само поле домена в XML.
<field name="model_name" invisible="1"/>
<field name="filter_domain" widget="domain"
options="{'model': 'model_name'}"/>
Без widget="domain" и опции с моделью поле отобразится как обычный текст — не забывайте указывать оба атрибута, если хотите дать пользователям визуальный редактор.
Запись доменов через XML‑RPC
Если пишете домен через API, передавайте значение как строку.
models.execute_kw(db, uid, api_key, 'my.model', 'write',
[[record_id], {
'filter_domain': "[('active', '=', True)]"
}]
)
Передача списка Python вместо строки — частая ошибка, приводящая к ошибке типа или тихому провалу в зависимости от версии Odoo. Всегда сериализуйте домен в строку при записи через API.
Рекомендации по использованию
Эти простые привычки помогут избежать проблем при работе с Domain‑полями.
Проверяйте синтаксис домена до деплоя
Неверный домен вызовет ошибку при попытке его оценить. Тестируйте домены в поиске Odoo или в режиме разработчика перед сохранением в автоматизацию или record rule. Вызов search_count через API — быстрый способ убедиться, что домен возвращает ожидаемое количество записей.
Используйте динамические переменные
Не захардкодьте ID пользователя, компании или даты в доменах. Применяйте uid, context_today(), current_company_id и похожие конструкции. Это делает фильтры переносимыми и устойчивыми при миграции между базами.
Всегда привязывайте контекст модели
Добавляя поле Domain в модель, указывайте model_field и включайте его в вид. Без этого пользователи увидят текстовое поле, а не визуальный редактор, что повышает риск неправильных значений.
Держите домены читаемыми
Сильно вложенные домены с | и & быстро становятся запутанными. Комментируйте сложные выражения в Python‑коде. Если логика слишком громоздка, подумайте о серверном действии или вычисляемом поле — они часто проще для тестирования и поддержки.
Для оценки используйте safe_eval
Если вам нужно программно оценить домен в Python, применяйте встроенный safe_eval, а не глобальный eval. Это безопаснее, корректно обрабатывает Odoo‑контекст и соответствует тому, как система делает это сама.
Тестируйте на реалистичных данных
Проверяйте домены на данных, близких к боевым. Особенно важно для автоматизаций и правил доступа — неверный фильтр может затронуть не те записи или скрыть их от пользователей без всяких предупреждений.
Типичные ошибки
Частые ошибки и как их избежать
Путаница между типом поля и синтаксисом домена
В Odoo «домен» означает и синтаксис фильтра, и тип поля fields.Domain. Новички часто путают: Domain‑поле — это место хранения выражения, а домен сам по себе — логика фильтрации внутри него.
Передача списка вместо строки через API
При записи через XML‑RPC домен нужно передавать как строку. Отправка «сырых» Python‑списков приведёт к ошибкам или тихим сбоям. Сериализуйте домен заранее.
Отсутствие контекста модели в виджете
Если в представлении не задать опции с моделью, виджет не поймёт, какие поля предлагать, и покажет простое текстовое поле. Всегда указывайте связь с моделью в options.
Хардкодинг ID записей в доменах
Домены, ссылающиеся на конкретные ID, ломаются при удалении записей или переносе конфигурации в другую базу. По возможности используйте динамические ссылки типа uid или реляционные фильтры.
Слишком широкие или слишком строгие record rules
Слишком свободный домен откроет лишние записи, слишком жесткий — скроет важные данные. Тестируйте права с учётом конкретной группы пользователей, а не с админскими полномочиями.
Забывчивость по поводу архивированных записей
По умолчанию Odoo исключает архивные записи (active = False) из поиска. Если вы хотите их учитывать, добавьте ('active', 'in', [True, False]) в домен, иначе получите неожиданные «дыры» в данных.
Выводы
Поле Domain — один из незаметных, но фундаментальных элементов Odoo. Оно отвечает за доступность данных, автоматические действия, динамические выпадающие списки и фильтры на дашбордах. fields.Domain даёт разработчикам валидное, структурированное место для хранения логики фильтрации прямо в модели данных.
Для бизнес‑пользователей визуальный редактор делает настройку фильтров понятной без кода. Для разработчиков Domain‑поле заменяет «костыль» с Char+виджетом, делая модель чище. Независимо от того, вы работаете в Studio, пишете модуль на Python или настраиваете автоматизации через интерфейс, понимание Domain открывает дополнительные возможности.
Положения этого обзора актуальны для разных версий и модулей Odoo. Вложенное время в изучение доменов окупается: они действительно вездесущи в платформе.
Нужна помощь с внедрением Odoo?
Dasolo помогает компаниям внедрять, настраивать и оптимизировать Odoo под конкретные бизнес‑задачи. Будь то автоматизация процессов, разработка модулей или улучшение текущей установки — наша команда обладает нужной экспертизой, чтобы дать уверенный результат.
Если у вас есть вопросы по Domain‑полям или другим аспектам Odoo, свяжитесь с нами,и мы с удовольствием посмотрим вашу конфигурацию и подскажем дальнейшие шаги.