Введение
Даты и метки времени — почти в каждой бизнес‑операции: заказ, доставка, приход сотрудника — везде нужен момент во времени. В Odoo для этого предусмотрено специализированное поле Datetime, которое служит единым источником правды для подобных отметок.
В отличие от простого поля Date, хранящего только календарную дату, Datetime сохраняет дату и точное время. Это важно, когда нужна точность по часам и минутам или когда пользователи работают из разных часовых поясов — тогда разница между «днём» и «моментом времени» становится существенной.
В этом материале собраны практические знания о поле Datetime в Odoo: что именно хранится, как поле представлено в модели данных, как добавить его через Studio или кодом, и реальные примеры применения в рабочих процессах.
Что такое поле Datetime в Odoo
В ORM Odoo fields.Datetime хранит комбинированное значение дата+время до секунд. На уровне базы данных это соответствует колонке TIMESTAMP в PostgreSQL. Внутри системы все значения сохраняются в UTC и при отображении переводятся в локальную часовую зону каждого пользователя.
Для пользователя поле Datetime выглядит как единый контрол с выбором даты и времени: календарь и поле для часов и минут. В списках и отчётах значение форматируется в соответствии с языком и часовым поясом текущего пользователя.
Пример объявления Datetime в Python‑модели показывает стандартный способ добавить такое поле в модель данных.
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_confirmed_on = fields.Datetime(
string='Confirmed On',
default=fields.Datetime.now,
readonly=True,
copy=False,
)
Параметр string задаёт подпись поля в интерфейсе; default — значение по‑умолчанию (заполняется при создании записи); readonly делает поле доступным только для чтения, что полезно для служебных меток времени.
В Odoo Studio этот тип называется «Date & Time». Поля, созданные через Studio, получают префикс x_studio_. При создании через код или API вы сами определяете техническое имя поля.
Как это поле работает
При добавлении Datetime в модель фреймворк автоматически создаёт соответствующую колонку в базе при установке или обновлении модуля — вручную писать миграции обычно не требуется.
Многие удивляются, как Odoo работает с часовыми поясами: в базе всегда хранится UTC. Если пользователь в Париже ставит встречу на 15:00, в базе это сохранится как 13:00 UTC; пользователь в Нью‑Йорке увидит время, скорректированное под его часовой пояс. ORM делает все переводы автоматически исходя из настроек профиля пользователя.
Ключевые атрибуты поля
Ниже — основные свойства Datetime-поля, которые чаще всего используются при разработке и настройке моделей.
- default: часто указывают
fields.Datetime.now, чтобы при создании записи автоматически проставлялся текущий UTC‑таймстамп. - required: делает поле обязательным для заполнения на уровне модели и формы.
- readonly: запрещает ручное редактирование в интерфейсе — удобно для системных меток времени.
- compute: связывает поле с методом Python, который вычисляет значение на основе других полей или логики.
- store: в сочетании с
computeсохраняет вычисленное значение в базе, что позволяет использовать его в фильтрах и отчётах. - copy: управляет копированием значения при дублировании записи. По‑умолчанию
True; для меток событий рекомендуетсяFalse. - index: создаёт индекс в базе — полезно для полей, по которым часто фильтруют (например, даты планируемых операций в больших таблицах).
Как поле отображается в интерфейсе
В формах Datetime рендерится как комбинированный селектор даты и времени: календарь + ввод часов/минут. В списках значение показывается в отформатированном виде по локали пользователя. В поиске поддерживаются фильтры по диапазону: до, после, между датами и временем.
Для планировочных задач удобно использовать виджет date_range, который позволяет выбирать интервал прямо в форме — это удобно для окон выполнения или временных рамок задач.
Datetime vs Date: как выбрать
Правило простое: если часовой компонент не важен — берите fields.Date, если важна точность до часов/минут — fields.Datetime. Неправильный выбор приводит к лишней сложности с часовыми поясами.
Используйте Date для: сроков оплаты, дней рождения, дат истечения срока годности, дат продления контрактов.
Используйте Datetime для: штампов подтверждения заказов, времени начала встреч, отметок прихода/ухода сотрудников, запланированных складских операций.
Применение Datetime там, где он не нужен, добавляет ненужную сложность и риск ошибок с часовыми поясами. Всегда проверяйте, действительно ли время дня важно для процесса.
Бизнес‑кейсы
Поле Datetime встречается почти во всех модулях Odoo. Ниже — пять практических примеров из реальной работы компаний.
CRM: учёт активности по лидам
В CRM Datetime‑поля фиксируют ключевые моменты: когда лид переведён в работу, когда назначен срок связи и т. п. Такие поля помогают измерять скорость реакции, выявлять «зависшие» лиды и отчётность по активности команды. Дополнительные пользовательские поля могут фиксировать момент отправки коммерческого предложения или время звонка.
Продажи: время подтверждения заказа
Поле date_order в sale.order — это Datetime, которое фиксирует момент подтверждения продажи. Оно важно для почасовой и суточной аналитики, расчёта времени обработки заказов и аудита последующих изменений. Фильтрация по этому полю — часть базовых отчётов по продажам.
Склад: планируемые даты перемещения
В stock.picking поле scheduled_date показывает, когда планируется приём или отгрузка. На его основе запускают автоматические действия: уведомления, эскалации или напоминания, например — письмо клиенту при просрочке отгрузки на несколько часов.
Производство: время запуска и завершения процессов
В производстве Datetime поля фиксируют начало и конец операций. Эти данные идут в планирование мощностей, анализ эффективности и вычисление простоя. На предприятиях с несколькими сменами точные временные метки помогают сопоставить план и фактический выпуск и находить узкие места по времени и операторам.
HR: учёт рабочего времени и отпусков
Модуль учёта посещаемости использует Datetime для отметок приходов и уходов. Запросы на отпуск могут ссылаться на точное время начала и окончания отсутствия. Зарплата и начисление переработок часто зависят от минутной точности. Пропуск или искажение метки времени в посещаемости сразу отражается на выплатах, поэтому точность здесь критична.
Создание и настройка поля Datetime
Добавить Datetime в модель можно тремя основными способами — выбор зависит от ваших навыков и требований к контролю версий.
Через Odoo Studio (без кода)
Studio — встроенный инструмент для быстрых настроек: он позволяет добавить поле без программирования. Пошагово:
- Откройте Odoo Studio из главного меню.
- Перейдите на форму, куда нужно добавить поле.
- Перетащите из панели «Date & Time» на форму.
- Задайте подпись, обязательность и, при необходимости, значение по‑умолчанию в свойствах поля.
- Сохраните изменения и закройте Studio.
Studio автоматически создаёт поле с префиксом x_studio_ и вносит его в представление. База обновится сама — вам не нужно писать миграции. Это оптимальный путь для бизнес‑пользователей, которым нужно быстро добавить метку времени без помощи разработчика.
Через Python в кастомном модуле
Если вы разработчик и хотите версионируемую кастомизацию, добавляйте поле в Python‑модели — это стандартный и рекомендуемый способ для продакшена:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_last_contact_date = fields.Datetime(
string='Last Contact Date',
default=fields.Datetime.now,
copy=False,
)
После объявления поля добавьте его в XML‑представление, чтобы он отображался в интерфейсе. Odoo автоматически создаст колонку TIMESTAMP при установке или обновлении модуля, ручной SQL не нужен.
Через XML‑RPC API
Если вы автоматизируете конфигурацию или делаете удалённые скрипты, поле можно создать программно через XML‑RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_last_contact_date',
'field_description': 'Last Contact Date',
'model_id': model_id,
'ttype': 'datetime',
'state': 'manual',
}]
)
Параметр ttype: datetime указывает тип поля, а state: manual отмечает, что поле создано вне установки модуля (как через Studio или API). Такой подход удобен для централизованных скриптов настройки клиентов.
Рекомендации по использованию
1. Используйте fields.Datetime.now как ссылку на функцию, а не её вызов
При указании значения по‑умолчанию пишите default=fields.Datetime.now без скобок. Если поставить скобки, функция выполнится при загрузке класса, и все новые записи в течение работы процесса получат одну и ту же «замороженную» дату. Без скобок функция вызывается при создании каждой записи отдельно.
2. Ставьте copy=False для меток событий
Для полей, фиксирующих момент события (подтверждение, завершение и т.п.), указывайте copy=False. При дублировании записи дата события не должна переноситься — иначе история и отчёты будут искажены.
3. Всегда передавайте UTC при работе через API
При записи через XML‑RPC передавайте строки в формате YYYY-MM-DD HH:MM:SS в UTC. API не делает автоматической переконвертации при записи — то, что вы передаёте, сохранится как UTC, поэтому локальное время без корректного перевода создаст смещение, которое потом трудно отловить.
4. Делайте системные метки readonly
Автогенерируемые временные метки лучше пометить как readonly в интерфейсе, чтобы пользователи их не правили вручную. Если же требуется корректировка, используйте механизмы прав доступа, а не оставляйте поле открытым для всех.
5. Выбирайте Date, если время не нужно
Если поле нужно лишь для календарного дня — срок платежа, дата продления — используйте fields.Date. Datetime в таких случаях добавляет лишнюю сложность из‑за часовых поясов и усложняет поддержку модели данных.
Типичные ошибки и ловушки
Путаница с часовыми поясами при чтении «сырого» значения
Частая проблема — чтение значения напрямую из базы или через API: вы получите UTC‑время, а не локальное. Многие интеграции строятся на «сырых» данных и в итоговой системе получаются сдвиги на несколько часов. Всегда конвертируйте UTC в локальную зону на стороне клиента при отображении.
Запись локального времени через API
Если вы отправите в API локальное время (например, 2026-01-01 15:00:00 для Парижа), база сохранит это как UTC. Из‑за перехода на летнее/зимнее время и различий в зонах пользователи увидят неверный час. Такие баги проявляются в продакшене, когда реальные пользователи начинают работать с системой из разных часовых зон.
Использование fields.Datetime.now() со скобками
Вызов fields.Datetime.now() при объявлении по‑умолчанию — тонкая, но серьёзная ошибка. Функция выполнится при загрузке класса, и все созданные после этого записи получат одно и то же время создания. Проблема долго не очевидна: метки есть, но они одинаковы и ломают аналитику по времени.
Забыть про copy=False для меток событий
Если не установить copy=False, при дублировании записи все Datetime‑поля скопируются, и, например, у новой заявки окажется дата подтверждения старой. Это тихая порча истории, делающая отчёты ненадёжными — мелкая настройка с большим эффектом на качество данных.
Использование Datetime там, где подходит Date
Выбор Datetime для простых календарных дат добавляет лишний тайм‑зонный оверхед и делает интерфейс громоздким: пользователи видят поле времени без пользы, а разработчики вынуждены учитывать временные сдвиги. Всегда моделируйте данные максимально просто, соответствуя требованиям бизнеса.
Заключение
Поле Datetime — одно из наиболее полезных в Odoo, когда нужна точность. Оно повсеместно: от фиксации открытия лида до отметок производства и прихода сотрудников.
Главное, что нужно запомнить — Odoo хранит всё в UTC. Интерфейс сам показывает локальное время, но внешние чтения/записи через API требуют явной обработки часовых поясов. Большинство багов интеграций связано именно с этим недопониманием.
Кроме этого, следите за правильной записью default, не забывайте ставить copy=False для событий и выбирайте Date там, где время не имеет значения — это сохранит модель данных понятной и отчёты корректными.
Наша компания помогает внедрять, настраивать и оптимизировать Odoo в разных департаментах. Мы проектируем корректные модели данных, добавляем нужные поля и пишем модули под ключ — от анализа требований до релиза. Свяжитесь с нами и обсудим ваш Odoo‑проект.