Chapter 7: Relations Between Models¶
The previous chapter covered the creation of custom views for a model containing basic fields. However, in any real business scenario we need more than one model. Moreover, links between models are necessary. One can easily imagine one model containing the customers and another one containing the list of users. You might need to refer to a customer or a user on any existing business model.
У нашому модулі нерухомості нам потрібна така інформація про нерухомість:
клієнт, який придбав нерухомість
the real estate agent who sold the property
тип нерухомості: будинок, квартира, пентхаус, замок…
перелік тегів, що характеризують нерухомість: затишно, з ремонтом…
перелік отриманих пропозицій
Many2one¶
Посилання: документацію, пов’язану з цією темою, можна знайти в Many2one
.
Примітка
Ціль: у кінці цього розділу:
слід створити нову модель
estate.property.type
з відповідним меню, діями та представленнями.

три поля Many2one слід додати до моделі
estate.property
: тип власності, покупець і продавець.

У нашому модулі нерухомості ми хочемо визначити поняття типу власності. Тип нерухомості – це, наприклад, будинок або квартира. Класифікація властивостей відповідно до їх типу, особливо для вдосконалення фільтрації, є стандартною для бізнесу.
Властивість може мати один тип, але той самий тип можна призначити багатьом властивостям. Це підтримується концепцією many2one.
Many2one – це просте посилання на інший об’єкт. Наприклад, щоб визначити посилання на res.partner
у нашій тестовій моделі, ми можемо написати:
partner_id = fields.Many2one("res.partner", string="Partner")
За домовленістю поля many2one мають суфікс _id
. Доступ до даних у партнері можна легко здійснити за допомогою:
print(my_test_object.partner_id.name)
Перегляньте також
На практиці many2one можна побачити як спадний список у представленні форми.
Exercise
Додайте таблицю типу нерухомості.
Створіть модель
estate.property.type
і додайте таке поле:
Поле |
Тип |
Атрибути |
---|---|---|
name |
Char |
обов’язкові |
Додайте меню, як показано в Цілі цього розділу
Додайте поле
property_type_id
до вашої моделіestate.property
та її представлень форми, списку та пошуку
This exercise is a good recap of the previous chapters: you need to create a model, set the model, add an action and a menu, and create a view.
Порада: не забудьте імпортувати нові файли Python у __init__.py
, додати нові файли даних у __manifest.py__
або додати права доступу ;-)
Ще раз перезапустіть сервер і оновіть, щоб побачити результати!
У модулі нерухомості все ще бракує двох частин інформації, яку ми хочемо про нерухомість: покупця та продавця. Покупцем може бути будь-яка фізична особа, але з іншого боку продавець повинен бути співробітником агентства нерухомості (тобто користувач Odoo).
В Odoo є дві моделі, які ми зазвичай називаємо:
res.partner
: партнер - фізична або юридична особа. Це може бути компанія, фізична особа або навіть контактна адреса.res.users
: користувачі системи. Користувачі можуть бути „внутрішніми“, тобто мати доступ до серверної частини Odoo. Або вони можуть бути „портальними“, тобто вони не можуть отримати доступ до серверної частини, лише до зовнішньої частини (наприклад, для доступу до своїх попередніх замовлень в електронній комерції).
Exercise
Додайте покупця та продавця.
Додайте покупця та продавця до моделі estate.property
за допомогою двох загальних моделей, згаданих вище. Їх слід додати на новій вкладці представлення форми, як показано в Цілі цього розділу.
Значенням за замовчуванням для продавця має бути поточний користувач. Покупця не варто копіювати.
Порада: щоб отримати значення за замовчуванням, перевірте примітку нижче або перегляньте приклад тут .
Примітка
Об’єкт self.env
надає доступ до параметрів запиту та інших корисних речей:
self.env.cr
абоself._cr
- об’єкт курсор бази даних; він використовується для запиту до бази данихself.env.uid
абоself._uid
це ідентифікатор бази даних поточного користувачаself.env.user
- це поточний запис користувачаself.env.context
абоself._context
- це контекстний словникself.env.ref(xml_id)
повертає запис, що відповідає ідентифікатору XMLself.env[model_name]
повертає екземпляр даної моделі
Тепер давайте розглянемо інші типи посилань.
Many2many¶
Посилання: документацію, пов’язану з цією темою, можна знайти в Many2many
.
Примітка
Ціль: у кінці цього розділу:
слід створити нову модель
estate.property.tag
із відповідним меню та дією.

теги слід додати до моделі
estate.property
:

У нашому модулі нерухомості ми хочемо визначити концепцію тегів власності. Тег власності – це, наприклад, нерухомість, яка є „затишною“ або „відремонтованою“.
Властивість може мати many тегів, а тег можна призначити many властивостям. Це підтримується концепцією many2many.
many2many - це двонаправлений множинний зв’язок: будь-який запис на одній стороні може бути пов’язаний із будь-якою кількістю записів на іншій стороні. Наприклад, щоб визначити посилання на модель account.tax
у нашій тестовій моделі, ми можемо написати:
tax_ids = fields.Many2many("account.tax", string="Taxes")
За домовленістю поля many2many мають суфікс _ids
. Це означає, що до нашої тестової моделі можна додати декілька податків. Він веде себе як список записів, тобто доступ до даних повинен здійснюватися в циклі:
for tax in my_test_object.tax_ids:
print(tax.name)
Список записів відомий як набір записів, тобто впорядкована колекція записів. Він підтримує стандартні операції Python над колекціями, такі як len()
і iter()
, а також додаткові операції з наборами, як recs1 | recs2
.
Exercise
Додайте таблицю тегів нерухомості.
Створіть модель
estate.property.tag
і додайте таке поле:
Поле |
Тип |
Атрибути |
---|---|---|
name |
Char |
обов’язкові |
Додайте меню, як показано в Цілі цього розділу
Додайте поле
tag_ids
до вашої моделіestate.property
, а також у представленнях її форми та списку
Tip: in the view, use the widget="many2many_tags"
attribute as demonstrated
here.
The widget
attribute will be explained in detail in a later chapter of the training.
For now, you can try to adding and removing it and see the result ;-)
One2many¶
Посилання: документацію, пов’язану з цією темою, можна знайти в One2many
.
Примітка
Ціль: у кінці цього розділу:
має бути створена нова модель
estate.property.offer
з відповідною формою та представлення списку.теги слід додати до моделі
estate.property
:

У нашому модулі нерухомості ми хочемо визначити концепцію пропозицій нерухомості. Пропозиція власності – це сума, яку потенційний покупець пропонує продавцю. Пропозиція може бути нижче або вище очікуваної ціни.
Пропозиція поширюється на one нерухомість, але одна й та сама нерухомість може мати many пропозицій. Знову з’являється концепція many2one. Однак у цьому випадку ми хочемо відобразити список пропозицій для певної власності, тому ми будемо використовувати концепцію one2many.
One2many є зворотним до a many2one. Наприклад, ми визначили в нашій тестовій моделі посилання на модель res.partner
завдяки полю partner_id
. Ми можемо визначити зворотне співвідношення, тобто список тестових моделей, пов’язаних з нашим партнером:
test_ids = fields.One2many("test_model", "partner_id", string="Tests")
Перший параметр називається comodel
, а другий параметр – це поле, яке ми хочемо інверсувати.
За домовленістю поля one2many мають суфікс _ids
. Вони ведуть себе як список записів, тобто доступ до даних має здійснюватися в циклі:
for test in partner.test_ids:
print(test.name)
Exercise
Додайте таблицю Пропозиція нерухомості.
Створіть модель
estate.property.offer
і додайте наступні поля:
Поле |
Тип |
Атрибути |
Значення |
---|---|---|---|
price |
Float |
||
status |
Selection |
немає копії |
Прийнято, Відмовлено |
partner_id |
Many2one ( |
обов’язкові |
|
property_id |
Many2one ( |
обов’язкові |
Створіть представлення списку та вигляд форми з полями
price
,partner_id
іstatus
. Не потрібно створювати дію чи меню.Додайте поле
offer_ids
до вашої моделіestate.property
і в її представленні форми, як показано в Цілі цього розділу.
Тут слід звернути увагу на кілька важливих речей. По-перше, нам не потрібна дія або меню для всіх моделей. Деякі моделі призначені для доступу лише через іншу модель. Це так у нашій вправі: доступ до пропозиції завжди здійснюється через властивість.
По-друге, незважаючи на те, що поле property_id
є обов’язковим, ми не включили його в представлення. Як Odoo дізнається, з якою нерухомістю пов’язана наша пропозиція? Що ж, це частина магії використання фреймворку Odoo: іноді речі визначаються неявно. Коли ми створюємо запис через поле one2many, відповідне поле many2one заповнюється автоматично для зручності.
Still alive? This chapter is definitely not the easiest one. It introduced a couple of new concepts while relying on everything that was introduced before. The next chapter will be lighter, don’t worry ;-)