Первые веб страницы на odoo

Содержание

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

Подготовка

Для того, чтобы использовать следующий пример, вам необходимо переключить текущий разрабатываемый проект на другую ветку.

Вот ее имя - 16.0-webpage-example

Затем удалите текущую базу и создайте новую.

Убедитесь, что у вас не осталось вкладок со старыми сессиями

В файл конфигурации в параметры init_modules и update_modules добавьте имя модуля first_module_public_page

Запустите менеджер с параметрами -d, -i, и -u

Перейдите откройте браузер по адресу http://127.0.0.1:8069/records/

Контроллеры

О том что такое контроллеры, можно почерпнуть из документации

У нас есть контроллеры, которые могут ответить на http запрос, который поступает к нашему экземпляру odoo. Контроллер это функция, которая обрабатывает http запрос направленный на конкретный URI на нашем сервере. Для того, чтобы указать какой именно URI, а так же метод запроса и другие параметры, необходимо задекорировать нашу функцию декоратором http.route:

Контроллер

  1. Декоратор http.route. Связывает указанные URI в первом параметре и функцию-обработчик, которой и является декорируемая функция. Параметры функции-декоратора можно увидеть здесь
  2. Декорируемая функция - обработчик запроса. Внутри нее происходит вся работа для формирования ответа на запрос
  3. Пример осуществления доступа к записям моделей. Обратите внимание, что доступ к объекту окружения env осуществляется не через self а с использованием импортируемого объекта request
  4. Обычный python словарь, который содержит значения для генерации(рендеринга) html строки, на базе Qweb шаблона. Ключи словаря будут доступны внутри шаблона как переменные
  5. В качестве результат работы функции здесь указан html, который в свою очередь генерируется с помощью указанного по xml_id шаблона и ранее описанного словаря значений

Как сгенерировать HTML

Пошаговое описание действий отрисовки html страницы в odoo

  1. Функция request.render выполняет формирование html на основании шаблона с xml_id first_module_public_page.first_model_public_list и передает туда словарь со значениями values
  2. Внутри шаблона вызывается шаблон xml_id first_module_public_page.base_layout , который по факту будет являться нашим родителем и представляет из себя упрощенную разметку html страницы. Красным цветом выделена директива, которая указывает где будет вставлен вызывающий его шаблон.
  3. Для того, чтобы отобразить весь список доступных записей, мы с помощью директивы t-foreach(внимательно смотрите официальную документацию) начинаем итерировать объект с именем all_records и присваиваем для переменной хранящей в себе объект шага итерации record. Как мы можем видеть all_records стал нам доступен после того, как мы добавили его в словарь values и передали в качестве аргумента функции request.render
  4. Если пользователь на первой странице нажмет на ссылку с записью браузер отправит запрос на указанный контроллер. Обратите внимание на то, как контроллером будет интерпретироваться числа стоящее после /records/. Любое число, находящееся в этом uri будет интерпретировано как значение поля id модели first.model и найденный рекордсет из одной записи будет передан в функцию обработчик как аргумент с указанным именем, в нашем случае это имя будет first_model_record_id. Так же обратите внимание на параметр auth=user, это говорит о том, что функция обработчик контроллера будет вызвана только для аутентифицированных пользователей, для гостей будет предложено ввести свой логин и пароль.
  5. Мы опять вызываем функцию request.render в которой указываем имя шаблона с xml_id first_module_public_page.first_model_public_item и словарем со значениями values
  6. Вызов родительского шаблона xml_id first_module_public_page.base_layout
  7. Использование объекта record из ранее созданного словаря значений values. Здесь мы просто обращаемся к атрибутам записи так же как и в коде python

Давайте теперь рассмотрим пример обработки одного запроса, но уже так, как его видит браузер:

Как это выглядит в браузере

  1. Отравляем запрос на сервер
  2. Видим HTML код, который нам прислал сервер и то, как его интерпретировал браузер в виде веб страницы.

Использование ассетов

Как вы уже могли заметить наша веб страница выглядит весьма аскетично для современного веба, но на данном этапе это было сделано намеренно для упрощения финально конструкции. Тем не менее в нашем примере вы так же найдете способы подключения css, js и других файлов, которые вам могут понадобится для построения вашей веб страницы. Собственно эти файлы и называются ассетами. Начиная с версии 15.0 Odoo требует объявления ассетов в __manifest__.py файле по ключу assets:

Использование ассетов

Как мы можем видеть, что в файле __manifest__.py мы сами придумали xml_id для нашего набора или бандла ассетов и затем применили его в шаблоне базовой страницы, который наследуют все остальные шаблоны. Обратите внимание что путь к файлам ассетов начинается с имени модуля. В шаблоне вы так же можете увидеть использование директив t-js="false" и t-css="false", они говорят что один бандл не содержит в себе css, а второй не содержит js файлов.

Безопасность

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

  1. Для начала я дал группе пользователей с xml_id base.group_public права на чтение модели first.model. Вы можете увидеть это здесь
  2. Все не аутентифицированные запросы попадающие на контроллер с параметром auth="public" автоматически присваиваются анонимному пользователю, который и входит в группу base.group_public. Таким образом при обращении к моделям и их записям автоматически будет применяться полный механизм безопасности Odoo. Да, конечно, вы можете использовать sudo() при работе из контроллера, но его использование необходимо максимально ограничить, т.к. с развитием проекта вы рискуете просто упустить из виду бреши в безопасности из-за роста кодовой базы и количества бесконтрольных обращений к системе.
  3. В случае же, если вам нужно скрыть страницу исключительно для аутентифицированных пользователей, вы в контроллере должны применять параметр auth="user", что автоматически вызовет проверку того, аутентифицирован ли пользователь на сайте или нет. И все обращения к ресурсам системы внутри контроллера уже будут авторизованы от его имени.

Обсуждение

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