Chapter 3: Models And Basic Fields¶
At the end of the previous chapter, we were able to create an Odoo module. However, at this point it is still an empty shell which doesn’t allow us to store any data. In our real estate module, we want to store the information related to the properties (name, description, price, living area…) in a database. The Odoo framework provides tools to facilitate database interactions.
Перш ніж рухатися вперед у вправі, переконайтеся, що модуль 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/,../tutorials/ -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/,../tutorials/ -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
)Користувач, який останній змінював запис.
Now that we have created our first model, let’s add some security!