Розділ 11: Обмеження

попередній розділ представив можливість додати деяку бізнес-логіку до нашої моделі. Тепер ми можемо зв’язати кнопки з бізнес-кодом, але як запобігти введенню користувачами неправильних даних? Наприклад, у нашому модулі нерухомості ніщо не заважає користувачам встановлювати негативну очікувану ціну.

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().

Примітка

Ціль: наприкінці цього розділу неможливо буде прийняти пропозицію, нижчу за 90% від очікуваної ціни.

Обмеження Python

Обмеження 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.

Наш модуль нерухомості починає виглядати добре. Ми додали деяку бізнес-логіку, і тепер ми гарантуємо узгодженість даних. Однак інтерфейс користувача все ще трохи грубий. Давайте подивимося, як ми можемо його покращити, у наступному розділі.