Розділ 4: Моделі та базові поля¶
Наприкінці попереднього розділу ми змогли створити модуль Odoo. Однак на даний момент це все ще порожня оболонка, яка не дозволяє нам зберігати жодні дані. У нашому модулі нерухомості ми хочемо зберігати інформацію, пов’язану з нерухомістю (назва, опис, ціна, житлова площа…) у базі даних. Фреймворк Odoo надає інструменти для полегшення взаємодії з базами даних.
Перш ніж рухатися вперед у вправі, переконайтеся, що модуль estate
встановлено, тобто він має відображатися як „Встановлено“ у списку додатків.
Попередження
Не використовуйте змінні глобальні змінні.
Один екземпляр Odoo може запускати кілька баз даних паралельно в одному процесі python. У кожній із цих баз даних можуть бути встановлені різні модулі, тому ми не можемо покладатися на глобальні змінні, які оновлюватимуться залежно від встановлених модулів.
Об’єктно-реляційне відображення¶
Довідка: документацію, пов’язану з цією темою, можна знайти в Моделі API.
Примітка
Мета: у кінці цього розділу має бути створена таблиця estate_property
:
$ psql -d rd-demo
rd-demo=# SELECT COUNT(*) FROM estate_property;
count
-------
0
(1 row)
Ключовим компонентом Odoo є рівень ORM. Цей рівень дозволяє уникнути необхідності вручну писати більшість SQL і забезпечує розширюваність і служби безпеки2.
Бізнес-об’єкти оголошуються як класи Python, що розширюють Model
, який інтегрує їх в автоматизовану систему збереження.
Моделі можна налаштувати, встановивши ряд атрибутів при їх визначенні. Найважливішим атрибутом є _name
, який є обов’язковим і визначає назву моделі в системі Odoo. Ось мінімально повне визначення моделі:
from odoo import models
class TestModel(models.Model):
_name = "test_model"
Цього визначення достатньо, щоб ORM створив таблицю бази даних під назвою test_model
. За домовленістю всі моделі розташовані в каталозі models
, і кожна модель визначається у власному файлі Python.
Подивіться, як визначається таблиця crm_recurring_plan
і як імпортується відповідний файл Python:
Модель визначається у файлі
crm/models/crm_recurring_plan.py
(див. тут)Файл
crm_recurring_plan.py
імпортується вcrm/models/__init__.py
(див. тут)Папка
models
імпортується вcrm/__init__.py
(див. тут)
Exercise
Визначте модель властивостей нерухомості.
На основі прикладу, наведеного в модулі CRM, створіть відповідні файли та папку для таблиці estate_property
.
Після створення файлів додайте мінімальне визначення для моделі estate.property
.
Будь-яка зміна файлів Python вимагає перезапуску сервера Odoo. Коли ми перезапустимо сервер, ми додамо параметри -d
і -u
:
$ ./odoo-bin --addons-path=addons,../enterprise/,../technical-training-sandbox/ -d rd-demo -u estate
-u estate
означає, що ми хочемо оновити модуль estate
, тобто ORM застосує зміни схеми бази даних. У цьому випадку створюється нова таблиця. -d rd-demo
означає, що оновлення має бути виконано в базі даних rd-demo
. -u
завжди слід використовувати в комбінації з -d
.
Під час запуску ви повинні побачити такі попередження:
...
WARNING rd-demo odoo.models: The model estate.property has no _description
...
WARNING rd-demo odoo.modules.loading: The model estate.property has no access rules, consider adding one...
...
Якщо це так, то вам має бути добре! Щоб переконатися, двічі перевірте за допомогою psql
, як показано в Ціль.
Exercise
Додати опис.
Додайте _description
до вашої моделі, щоб позбутися одного з попереджень.
Поле моделі¶
Довідка: документацію, пов’язану з цією темою, можна знайти в Моделі API.
Поля використовуються для визначення того, що може зберігати модель і де вони зберігаються. Поля визначаються як атрибути в класі моделі:
from odoo import fields, models
class TestModel(models.Model):
_name = "test_model"
_description = "Test Model"
name = fields.Char()
Поле name
є Char
, яке буде представлено як str
Python Unicode і VARCHAR
SQL.
Типи¶
Примітка
Ціль: наприкінці цього розділу до таблиці estate_property
слід додати кілька основних полів:
$ psql -d rd-demo
rd-demo=# \d estate_property;
Table "public.estate_property"
Column | Type | Collation | Nullable | Default
--------------------+-----------------------------+-----------+----------+---------------------------------------------
id | integer | | not null | nextval('estate_property_id_seq'::regclass)
create_uid | integer | | |
create_date | timestamp without time zone | | |
write_uid | integer | | |
write_date | timestamp without time zone | | |
name | character varying | | |
description | text | | |
postcode | character varying | | |
date_availability | date | | |
expected_price | double precision | | |
selling_price | double precision | | |
bedrooms | integer | | |
living_area | integer | | |
facades | integer | | |
garage | boolean | | |
garden | boolean | | |
garden_area | integer | | |
garden_orientation | character varying | | |
Indexes:
"estate_property_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"estate_property_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
"estate_property_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL
Існує дві широкі категорії полів: „прості“ поля, які є атомарними значеннями, що зберігаються безпосередньо в таблиці моделі, і „реляційні“ поля, які пов’язують записи (одних і тих самих або різних моделей).
Прості приклади полів Boolean
, Float
, Char
, Text
, Date
і Selection
.
Exercise
Додайте основні поля до таблиці Нерухомість.
Додайте в таблицю такі основні поля:
Поле |
Тип |
---|---|
name |
Char |
description |
Text |
postcode |
Char |
date_availability |
Дата |
expected_price |
Float |
selling_price |
Float |
bedrooms |
Integer |
living_area |
Integer |
facades |
Integer |
garage |
Boolean |
garden |
Boolean |
garden_area |
Integer |
garden_orientation |
Selection |
Поле garden_orientation
повинно мати 4 можливі значення: „Північ“, „Південь“, „Схід“ і „Захід“. Список вибору визначається як список кортежів, приклад див. тут.
Коли поля додано до моделі, перезапустіть сервер за допомогою -u estate
$ ./odoo-bin --addons-path=addons,../enterprise/,../technical-training-sandbox/ -d rd-demo -u estate
Підключіться до psql
і перевірте структуру таблиці estate_property
. Ви помітите, що до таблиці також додано кілька додаткових полів. Ми переглянемо їх пізніше.
Загальні атрибути¶
Примітка
Ціль: у кінці цього розділу стовпці name
і expected_price
не повинні мати значення null в таблиці estate_property
:
rd-demo=# \d estate_property;
Table "public.estate_property"
Column | Type | Collation | Nullable | Default
--------------------+-----------------------------+-----------+----------+---------------------------------------------
...
name | character varying | | not null |
...
expected_price | double precision | | not null |
...
Подібно до самої моделі, її поля можна налаштувати, передавши атрибути конфігурації як параметри:
name = fields.Char(required=True)
Деякі атрибути доступні для всіх полів, ось найпоширеніші:
string
(unicode
, за умовчанням: назва поля)Мітка поля в інтерфейсі користувача (видима користувачами).
required
(bool
, за умовчанням:False
)Якщо
True
, поле не може бути порожнім, воно повинно або мати значення за замовчуванням, або завжди мати значення під час створення запису.help
(str
, за умовчанням:''
)Надає розширену довідкову підказку для користувачів в інтерфейсі користувача.
index
(bool
, за умовчанням:False
)Запитує, щоб Odoo створив індекс бази даних для стовпця.
Exercise
Встановити атрибути для існуючих полів.
Додайте такі атрибути:
Поле |
Атрибут |
---|---|
name |
обов’язкові |
expected_price |
обов’язкові |
Після перезапуску сервера обидва поля не повинні мати значення NULL.
Автоматичні поля¶
Посилання: документацію щодо цієї теми можна знайти в Автоматичні поля.
Можливо, ви помітили, що ваша модель має кілька полів, які ви ніколи не визначали. Odoo створює кілька полів у всіх моделях1. Ці поля керуються системою, і в них не можна записувати, але їх можна прочитати, якщо це буде корисно або необхідно:
id
(Id
)Унікальний ідентифікатор для запису моделі.
create_date
(Datetime
)Дата створення запису.
create_uid
(Many2one
)Користувач, який створив запис.
write_date
(Datetime
)Дата останньої зміни запису.
write_uid
(Many2one
)Користувач, який останній змінював запис.
Тепер, коли ми створили нашу першу модель, давайте додамо трохи безпеки!