Перейти к содержимому

Related Field в Odoo: Полное руководство по использованию поля-ссылки

Практическое руководство по полю Related в Odoo: принцип действия, случаи применения и настройка через Studio и на Python
6 марта 2026 г. от
Related Field в Odoo: Полное руководство по использованию поля-ссылки
Dasolo
| Комментариев пока нет

Введение


Если вы работали с моделью данных в Odoo, наверняка сталкивались с ситуацией, когда нужно показать на форме значение, хранящееся в связанном документе, не перебирая записи вручную. Для таких задач в Odoo существует Related-поле — декларативный способ «подтянуть» значение из другой модели прямо на текущую форму.


Вместо того чтобы писать вычисляемое поле с Python-методом, Related-поле просто проходит по цепочке связей и показывает итоговое значение. Это очень удобный инструмент как для разработчиков, так и для консультантов, которые используют Odoo Studio и хотят добавить контекстную информацию без программирования.


В этом материале мы разберём, что именно хранит Related-поле, как оно работает внутри ORM Odoo, как его создать через Studio и в коде, и в каких рабочих сценариях оно окажется полезным.

Что такое Related-поле в Odoo


В ORM Odoo Related — это не отдельный тип данных наподобие Float или Char, а скорее «ярлык», который ссылается на поле другой модели. Фактически поле наследует тип конечного поля в цепочке связей и отображает его значение на текущей модели.


Простой пример: в заказе на продажу есть поле partner_id (Many2one на res.partner). Related-поле с связью partner_id.country_id выведет страну клиента прямо в форме заказа — без дублирования данных в новой колонке.

С точки зрения интерфейса Related-поле выглядит как обычное поле формы: если на конце цепочки Char — вы получите текстовое поле, Many2one — выпадающий список, Boolean — флажок. Визуально оно повторяет поведение того поля, на которое ссылается.


По умолчанию Related-поля являются только для чтения и не сохраняются в БД. Это значит, что они всегда показывают актуальное значение из источника, но не подходят для прямой фильтрации или группировки, если не включить store=True.


В Odoo Studio создание Related-поля максимально простое: при добавлении поля выбираете путь связей, и Studio автоматически создаёт поле с нужной конфигурацией — удобный вариант для консультантов, которые хотят быстро дополнить форму без кода.

Принцип работы поля Related


Когда Odoo читает Related-поле, оно проходит по именам полей, разделённым точками. Все звенья, кроме последнего, должны быть реляционными (Many2one, One2many, Many2many), а заключительное звено может быть любого типа.


Ниже приведён типовой пример определения Related-поля в модуле на Python.


from odoo import fields, models

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    partner_country_id = fields.Many2one(
        related='partner_id.country_id',
        string='Customer Country',
        store=True,
    )

В этом фрагменте Odoo сперва переходит по partner_id к записи res.partner, затем читает country_id и в итоге отображает Many2one-поле с информацией о стране на уровне заказа.


Сохранённые и несохранённые Related-поля

Главное различие — по умолчанию store=False: значение вычисляется «на лету» при чтении записи и не хранится в таблице модели.


Если указать store=True, значение будет записываться в колонку БД при изменении источника. Это даёт возможность фильтровать, группировать и искать по полю — важно для отчётов и списков.


Минус в том, что хранимые Related-поля занимают место в БД и требуют триггера обновления при изменениях источника. Odoo автоматически отслеживает зависимости, но при больших объёмах данных стоит учитывать нагрузку.


Только для чтения и записываемые Related-поля

По умолчанию Related-поля только для чтения. Если задать readonly=False, поле становится редактируемым: при изменении Odoo запишет новое значение обратно по цепочке в исходную запись. Это удобно, но может удивить пользователя, потому что изменение на форме заказов фактически меняет связанную запись партнёра.


Используйте writable Related-поля только когда намерение — запись в исходный объект. Для быстрых правок в списке это удобно, но при нечётком понимании бизнес-пользователями приведёт к непредвиденным изменениям общих данных.


Ключевые атрибуты поля

Ниже перечислены основные параметры, которыми управляют Related-полем:

  • related: цепочка имен полей через точки (например, 'partner_id.country_id'). Это обязательный параметр.
  • store: True — сохранять значение в БД для возможности фильтрации и группировки.
  • readonly: False — позволить редактировать поле, что приведёт к записи в исходную модель.
  • string: подпись поля, видимая пользователю; по умолчанию берётся от конечного поля.
  • depends: обычно не нужен, так как Odoo сам выводит зависимости из related-цепочки; пригоден в редких, специфичных случаях.

Взаимодействие с ORM Odoo

Чтение Related-поля возвращает значение конечного поля в связанной записи. Если какой-то звено цепочки пустое (например, partner_id не задан), результатом будет False — стандартная логика ORM для реляционных полей.


Если поле сохранено (store=True), его можно использовать в доменах, представлениях и отчётах. Несохранённые поля отображаются в форме и списке, но не служат критерием поиска, пока сервер не оценит их на стороне Python вместо SQL.

Бизнес-кейсы применения


Related-поля встречаются почти во всех частях Odoo. Ниже — пять практических сценариев из реальных бизнес-процессов.


CRM и продажи: телефон клиента в заказе

Отдел продаж часто просит видеть телефон покупателя прямо на форме заказа. Related-поле с partner_id.phone решает это за пару кликов: телефоны отображаются в контексте заказа, ускоряя прозвон и убирая необходимость открывать карточку партнёра. В Studio такую настройку можно сделать за минуту.


Бухгалтерия: валюта компании в строках счёта

В мультикомпанейных конфигурациях бухгалтерам удобно видеть валюту компании на строках счёта. Related-поле, например move_id.company_id.currency_id, проходит по двум связям и показывает валюту. Хотя цепочки на два шага работают нормально, длинные цепочки лучше держать в рамках ради производительности. Сохранённое поле позволяет фильтровать и группировать проводки по валюте в аналитических отчётах.


Склад: категория товара в записях перемещения

Складские операторы порой нуждаются в категории товара прямо в строке stock.move.line, чтобы не заходить в карточку продукта. Related-поле product_id.categ_id предоставляет эту информацию. При store=True вы сможете группировать перемещения по категориям в отчётах Инвентаря — это полезно при большом ассортименте.


Производство: внутренний код на компонентах рабочего задания

В производстве оператору на участке важно видеть внутренний артикул компонента прямо в списке операций. Related-поле product_id.default_code на строке mrp.workorder даёт этот артикул в нужном месте, сокращая ошибки при подборе похожих деталей и повышая точность сборки.


Таймшиты и проекты: подразделение сотрудника

Руководитель проекта при анализе учёта рабочего времени часто хочет видеть, к какому отделу принадлежит сотрудник. Related-поле employee_id.department_id на account.analytic.line показывает отдел в строке таймшита. При store=True такие строки можно фильтровать по отделам в отчётах по проектам, что важно для распределения затрат и ресурсов.

Как создать или настроить Related-поле


Три способа добавить Related-поле в модель Odoo


Способ 1 — Odoo Studio (без кода)

Studio позволяет создать Related-поле без программирования. Алгоритм действий простой:

  1. Откройте Odoo Studio из главного меню.
  2. Перейдите на форму, куда хотите добавить поле.
  3. Нажмите «Добавить поле» и выберите «Related Field».
  4. Пошагово укажите путь связей, кликая по доступным полям.
  5. Задайте подпись и опции: хранить или только для чтения.
  6. Сохраните изменения и выйдите из Studio.

Studio создаст поле с префиксом x_studio_ и поместит его в представление. Это быстрый и гибкий способ добавить контекстные данные без вмешательства в базу или код.


Способ 2 — Python в кастомном модуле

Для разработчиков, которые работают через код и нуждаются в управляемой, версионируемой настройке, Related-поля объявляют в классе модели — это рекомендуемый подход для стабильных кастомизаций и деплоя в несколько окружений:


from odoo import fields, models

class StockMoveLine(models.Model):
    _inherit = 'stock.move.line'

    product_category_id = fields.Many2one(
        related='product_id.categ_id',
        string='Product Category',
        store=True,
    )

После объявления добавьте поле в XML представление, чтобы оно стало видимым в интерфейсе. При установке или обновлении модуля Odoo сам создаст колонку в базе — стандартный путь для поддерживаемых кастомизаций.


Способ 3 — через XML-RPC API

Если конфигурация управляется программно (например, автоматизированные скрипты развёртки), Related-поля можно создать через XML-RPC, задав атрибут related в определении поля.

field_id = models.execute_kw(
    ODOO_DB, uid, ODOO_API_KEY,
    'ir.model.fields', 'create',
    [{
        'name': 'x_partner_country_id',
        'field_description': 'Customer Country',
        'model_id': sale_order_model_id,
        'ttype': 'many2one',
        'relation': 'res.country',
        'related': 'partner_id.country_id',
        'store': True,
        'readonly': True,
        'state': 'manual',
    }]
)

При создании через API нужно вручную указать ttype и relation, потому что API не выводит тип из цепочки так, как это делает Python ORM. Такой подход удобен для автоматизированного развёртывания полей в нескольких базах.

Рекомендации по использованию


Практические правила

1) Ставьте store=True, если поле будет использоваться в фильтрах или группировках. Без этого Odoo не сможет применить такой фильтр на уровне БД, и попытки поиска будут либо неэффективны, либо неверны. Для информационных полей в форме хранение необязательно.


2) Держите цепочку короткой. Двухуровневая цепочка (partner_id.country_id) — оптимальна. Глубокие цепочки сложнее отлаживать и более подвержены ошибкам; если требуется сложная логика, рассмотрите вычисляемое поле на Python.

3) Чётко понимайте значение readonly=False. Редактируемое Related-поле не копирует данные локально — оно правит исходную запись. Убедитесь, что пользователи осознают, что правки затронут общий объект.


4) Используйте Related-поля для отображения данных, а не для их дублирования. Если нужен независимый от источника столбец — лучше обычное поле с заполнением через onchange или автоматизацию, а не Related с store=True и readonly=False.

5) Проверьте права доступа. Если у пользователя нет прав чтения на промежуточную модель, Related-поле будет пустым. Это корректное поведение безопасности, но может запутать пользователей; предусмотрите соответствующие роли и тесты.


Распространённые ошибки

Фильтрация по несохранённому Related-полю


Одна из самых частых проблем — добавление Related-поля в список и попытка сразу же использовать его в поиске. Если store=False, фильтр не сработает на уровне SQL: домен вернёт ошибку либо пустой результат. Всегда ставьте store=True для полей, по которым будете фильтровать или группировать.

Неожиданная запись в исходную модель

Типичные ошибки и ловушки


Ещё частая ловушка — сделать Related-поле редактируемым и удивиться, что изменение затронуло исходный объект (например, партнёра). Это особенно характерно для полей, созданных через Studio пользователями без технического опыта. Перед включением возможности редактирования согласуйте поведение с бизнесом.

Пустые промежуточные звенья в цепочке


Если любое звено цепочки пустое, Related-поле вернёт False и на форме отобразится пустая ячейка. В коде, который читает это поле, нужно обрабатывать такой случай, иначе можно получить TypeError. Эту ситуацию легко пропустить в тестах, когда у тестовых записей все поля заполнены, но она проявится в продакшене.

Использование Related там, где нужен computed-подход


Related-поля хороши для простого «подтягивания» значения. Если требуется трансформация, условная логика или несколько источников — лучше писать computed-поле на Python. Попытки обойти ограничения Related-цепочки ведут к хрупким решениям, которые ломаются при обновлениях Odoo.

Проблемы с производительностью при большом количестве сохранённых Related-полей


Каждое store=True Related-поле требует обновления при изменении источника. Если на модели повешено много таких полей и объём записей большой, это создаёт значительную нагрузку на запись в БД. Для масштабных решений профилируйте влияние и отдавайте предпочтение несохранённым полям, если не нужна моментальная точность данных.

Итог — когда стоит использовать Related-поле


Related-поле — эффективный инструмент для вывода контекстной информации без дублирования. Оно позволяет пройти по цепочке связей, показать связанные значения в любом представлении и при необходимости сохранить их для отчётности и поиска.

Понимание момента, когда включать store=True, когда разрешать запись через readonly=False и как обрабатывать пустые промежуточные звенья, поможет избежать распространённых проблем при внедрении Odoo. Независимо от того, пишете ли вы модули на Python, делаете кастомизацию через Studio или управляете конфигурациями удалённо, Related-поле стоит держать в арсенале.

Заключение


Если вы проектируете или расширяете модель данных в Odoo, Related-поля должны соседствовать в вашем наборе инструментов с computed-полями, Many2one и другими типами полей, о которых идёт речь в этой серии.


В компании Dasolo мы помогаем внедрять, настраивать и оптимизировать Odoo для отделов продаж, операций, бухгалтерии и других подразделений. Если нужна помощь с проектированием модели данных, добавлением кастомных полей или расширением Odoo надёжным кодом — можем взять это на себя.

Свяжитесь с нами

и обсудим, как поддержать ваш Odoo-проект. Свяжитесь с нами и обсудим, чем можем помочь в реализации вашего проекта на Odoo.

Related Field в Odoo: Полное руководство по использованию поля-ссылки
Dasolo 6 марта 2026 г.
Поделиться этой записью
Войти оставить комментарий

Читать далее
Вычисляемые и Stored Computed Fields в Odoo: Полное руководство
Разберитесь, как в Odoo работают вычисляемые поля с сохранением значения: когда они нужны и как их создавать — через Python-код или с помощью Odoo Studio. Эта статья объяснит принципы хранения вычисленных результатов, подскажет сценарии, в которых имеет смысл сохранять значение (чтобы ускорить отчёты и сортировку, сохранять исторические данные или уменьшить нагрузку на вычисления), и пошагово покажет реализацию — от написания метода @api.depends и определения поля fields.Float/Char с параметром store=True до настройки триггеров и обновления при изменении зависимостей. Также рассмотрим альтернативы: когда лучше использовать не сохраняемые вычисляемые поля, функции-ассеты и автоматические действия в Studio, а когда — полноценное поле в базе. В конце — типичные ошибки (неправильные depends, слишком частые пересчёты, пропуск обновления при изменении связанных записей) и советы по тестированию, миграциям и производительности.