Модели

С подробной документацией вы можете ознакомиться здесь - Документация по моделям. В этой статье я расскажу базовые концепции, которые авторам документации кажутся очевидными, а вот у новичков вызывают много вопросов. В любой непонятной ситуации читайте документацию).

Модель в odoo - это основная абстракция с которой предстоит взаимодействовать разработчику. Есть три типа моделей:

  1. Абстрактная модель
  2. Стандартная модель
  3. Временная модель

Модель(здесь и далее мы будем иметь ввиду именно Стандартную модель) - это комплексная абстракция, которая объединяет класс python при этом состояние этого класса(значения атрибутов) хранятся в базе данных.

Имя модели

  1. Имя модели задается параметром _name в классе модели. Обратите внимание на стиль наименования, в нем резделителем слов является точка.
  2. Это же имя модели мы можем увидеть уже в адресной строке, это пример того, что имена моделей используются много где внутри системы
  3. после установки или обновления модуля, система сама создаст таблицу в базе данных с именем модели, но точки будут заменены на символ _(подчеркивание)

Т.е. создавая объявляя класс модели мы автоматически создаем таблицу, имя которой соответствует имени модели, а атрибуты класса - это поля(столбцы) таблицы:

Имя модели

  1. Здесь вы можете видеть как мы объявили поле name и в таблице тоже появилось такое поле, и это же поле мы можем видеть уже в веб-интерфейсе. Обратите внимание что имя поля в базе данных соответствует имени переменной в классе модели. А в интерфейсе отображается значение атрибута string переменной name
  2. Здесь мы можем видеть объявленное поле field_one

Как вы уже заметили, у нас в что в интерфейсе, что базе данных уже есть записи:

Записи

Набор записей(Рекордсет)

Мы уже знаем что класс модели описывает то, какая таблица и с какими полями будет создана в базе данных. А чему в python соответствуют записи в базе? По моим наблюдениям это самый неочевидный момент для новичков. Для того, чтобы это понять, придется разобраться с тем, что такое класс и экземпляр класса (Почитать можно на русском на английском). Когда вы уже примерно представляете что это такое, продолжим: В odoo есть дополнительная абстракция - рекордсет или набор записей(НЗ), данная абстракция является экземпляром класса модели который содержит в себе информацию о некоторых записях, каких именно уже определяется самой написанной программой. Рекордсеты делятся на 3 вида:

  1. Рекордсет без записей - не содержит в себе данных ни об одной записи модели, но вы можете воспользоваться методом модели, чьим экземпляром является данный рекордсет.
  2. Рекордсет с одной записью - содержит в себе данный одной записи модели.
  3. Рекордсет с более чем одной записью - содержит в себе информацию о множестве записей модели.

В классе модели мы так же описываем методы, которые собственно и производят вычисления. Если вы внимательно изучили информацию о классах, то уже знаете что первым аргументом метода(функции входящей в состав класса) является self и он же является экземпляром класса в момент выполнения метода. В нашем случае это и есть рекордсет. В разные моменты времени его значение может быть разным:

Рекордсет из 3-х записей

  1. Добавим в код команду print("self", self) - как и было сказано выше в self у нас будет находится рекородсет
  2. Теперь давайте нажмем пункт меню, который отправит команду о том, что мы хотим вывести несколько записей в виде списка (об этом подробнее я напишу позже)
  3. Мы увидим уже знакомые три записи
  4. А вот тут уже мы видим что в консоль вывелось имя модели с номерами в круглых скобках, в мы видим что у нас три номера.
  5. Номера которые отобразила команда print("self", self) соответствует значению поля IDв базе данных. Это служебное поле и создается системой автоматически при создании записи(Об этом позже расскажу).

А теперь давайте нажмем в интерфейсе на запись с именемrecord 001:

Рекордсет из одной записи

В этом случае мы открываем одну запись и видим что в self у нас находится рекордсет с одной записью.

Еще важный неочевидный момент для новичков - рекордсет и записи в базе данных это не одно и тоже. Каждый раз система создает новый рекордсет она обращается к базе данных и запрашивает из нее нужные данные и создает на базе соответствующих записей рекордсет. А когда мы присваиваем какое либо значение полю то это значение не мгновенно попадает в базу, а ждет момента пока пройдут все вычисления и уже после этого результат всех вычислений попадает в базу.

Обратите внимание на то, что в случае, когда у нас в self может НЗ с несколькими записями мы в цикле перебираем записи по одной. В этом случае каждым элементом буде уже рекордсет состоящий из одной записи.

Рекордсет из одной записи

Обратите внимание что считывание из присвоение значений полям может происходить только для рекордсета из одной записи(На самом деле это не совсем так, но пока не будем заострять на этом внимание)

record.result_field = record.field_one * record.field_two

В этом примере мы видим как присваивается значение полю result_field которое равно значению поля field_one умноженным на значение поля field_two. Как вы понимаете для каждой записи значения будут свои.

Задания для самостоятельного повторения:

  1. Повторите действия из статьи самостоятельно
  2. Оставьте обе команды print, которые были показаны
  3. Добавьте самостоятельно через интерфейс 4-ю запись и заполните своими значениями
  4. Посмотрите что выводится в консоли при выводе списка записей и при входе в каждую запись.

Обсуждение

Обсудить, указать на ошибки и опечатки можно здесь