Chapter 10: Constraints¶
The previous chapter introduced the ability to add some business logic to our model. We can now link buttons to business code, but how can we prevent users from entering incorrect data? For example, in our real estate module nothing prevents users from setting a negative expected price.
Odoo надає два способи налаштування автоматично перевірених інваріантів: Обмеження Python
і Обмеження SQL
.
SQL¶
Посилання: документацію, пов’язану з цією темою, можна знайти в Моделі і в документації PostgreSQL.
Примітка
Ціль: у кінці цього розділу:
Суми мають бути (строго) позитивними

Типи властивостей і теги повинні мати унікальну назву

Обмеження SQL визначаються через атрибут моделі _sql_constraints
. Цьому атрибуту призначається список потрійок, що містить рядки (name, sql_definition, message)
, де name
- дійсна назва обмеження SQL, sql_definition
- вираз table_constraint і message
це повідомлення про помилку.
Простий приклад можна знайти тут.
Exercise
Додайте обмеження SQL.
Додайте такі обмеження до відповідних моделей:
Очікувана ціна нерухомості має бути суто позитивною
Ціна продажу майна має бути позитивною
Ціна пропозиції повинна бути суто позитивною
Назва тегу властивості та назва типу властивості мають бути унікальними
Порада: знайдіть ключове слово unique
у кодовій базі Odoo для прикладів унікальних назв.
Перезапустіть сервер із опцією -u estate
, щоб побачити результат. Зауважте, що у вас можуть бути дані, які перешкоджають встановленню обмеження SQL. Може з’явитися таке повідомлення про помилку:
ERROR rd-demo odoo.schema: Table 'estate_property_offer': unable to add constraint 'estate_property_offer_check_price' as CHECK(price > 0)
Наприклад, якщо деякі пропозиції мають нульову ціну, обмеження не можна застосувати. Ви можете видалити проблемні дані, щоб застосувати нові обмеження.
Python¶
Посилання: документацію, пов’язану з цією темою, можна знайти в constrains()
.
Примітка
Goal: at the end of this section, it will not be possible to accept an offer lower than 90% of the expected price.

Обмеження SQL є ефективним способом забезпечення узгодженості даних. Однак може знадобитися виконати більш складні перевірки, для яких потрібен код Python. У цьому випадку нам потрібне обмеження Python.
Обмеження Python визначається як метод, прикрашений constrains()
і викликається в наборі записів. Декоратор визначає, які поля задіяні в обмеженні. Обмеження автоматично оцінюється, коли будь-яке з цих полів змінено. Очікується, що метод викличе виняток, якщо його інваріант не задовольняється:
from odoo.exceptions import ValidationError
...
@api.constrains('date_end')
def _check_date_end(self):
for record in self:
if record.date_end < fields.Date.today():
raise ValidationError("The end date cannot be set in the past")
# all records passed the test, don't return anything
Простий приклад можна знайти тут <https://github.com/odoo/odoo/blob/274dd3bf503e1b612179db92e410b336bfaecfb4/addons/stock/models/stock_quant.py#L239-L244>`__.
Exercise
Додайте обмеження Python.
Додайте обмеження, щоб ціна продажу не була нижчою за 90% від очікуваної ціни.
Порада: ціна продажу дорівнює нулю, доки пропозиція не буде підтверджена. Вам потрібно буде точно налаштувати свій чек, щоб врахувати це.
Попередження
Завжди використовуйте методи float_compare()
і float_is_zero()
з odoo.tools.float_utils
під час роботи з плаваючими значеннями!
Переконайтеся, що обмеження спрацьовує кожного разу, коли ціна продажу або очікувана ціна змінюється!
Обмеження SQL зазвичай ефективніші, ніж обмеження Python. Коли продуктивність має значення, завжди віддавайте перевагу SQL над обмеженнями Python.
Our real estate module is starting to look good. We added some business logic, and now we make sure the data is consistent. However, the user interface is still a bit rough. Let’s see how we can improve it in the next chapter.