Введение
В Odoo вся бизнес‑информация хранится в моделях — это не просто таблицы, а правила структуры данных. Любая запись, с которой вы работаете (статья, заказ, контакт), — это объект модели в базе данных.
Модели в Odoo — это скелет данных: поля, связи и встроенная логика. Понимание принципов моделей важно как разработчикам, так и консультантам, чтобы правильно настраивать систему и предсказывать поведение данных.
В этой заметке мы разбираем модель blog.post — именно она отвечает за блоги на сайтах Odoo. Независимо от того, пишете ли вы статьи через интерфейс, публикуете их через API или делаете кастомные доработки, вы будете взаимодействовать с этой моделью.
Что такое модель blog.post
Модель blog.post представляет одну публикацию блога в Odoo — каждую отдельную страницу с материалом на сайте. Один объект модели соответствует одной статье.
Эта модель входит в модуль website_blog и работает в связке с блог‑контейнером blog.blog и тегами blog.tag. Когда вы создаёте или редактируете статью в интерфейсе сайта, вы фактически создаёте или меняете запись blog.post.
Модель использует наследование от нескольких миксинов. Например, mail.thread отвечает за «чаттер» и подписчиков, а website.published.mixin — за логику публикации. Учёт этих наследований важен при расширениях, чтобы не испортить поведение.
blog.post — обычная сохраняемая модель (не абстрактная и не transient). Все записи хранятся в базе и доступны через API для чтения и модификации.
Ключевые поля модели
Ниже перечислены ключевые поля модели blog.post — знание их назначения облегчит работу с контентом и интеграциями.
1. name
Тип: Char. Заголовок статьи. Обязательное поле, отображается в списках, формах и на сайте. Он попадает в заголовок вкладки браузера и результаты поиска.
2. blog_id
Тип: Many2one (blog.blog). Связывает статью с конкретным блогом‑контейнером. Каждая запись относится ровно к одному блогу — используйте это для разделения по разделам (новости, обновления, инструкции).
3. subtitle
Тип: Char. Короткая подстрока или слоган, показываемый под заголовком. Полезен для улучшения читаемости и SEO‑сниппетов.
4. content
Тип: Html. Основное тело статьи. Хранит форматированный HTML — текст, изображения и сниппеты сайта. Это ключевое поле для содержимого.
5. teaser
Тип: Text. Автоматически генерируемый анонс из content. Используется в списках статей и является вычисляемым, только для чтения.
6. teaser_manual
Тип: Text. Ручная замена анонса. Если задано, выводится вместо автоматически сгенерированного текста — удобно для кастомных превью.
7. author_id
Тип: Many2one (res.partner). Автор публикации. Ссылка на контакт или пользователя, выводится на странице статьи — удобно при мультинаписательской структуре.
8. author_name
Тип: Char. Вычисляемое отображаемое имя автора. Подставляется из связанного контакта при наличии author_id; поле только для чтения.
9. author_avatar
Тип: Binary. Аватар автора — картинка, показываемая рядом с именем. Поле необязательное.
10. is_published
Тип: Boolean. Показывает, видна ли статья на сайте. Это вычисляемое поле только для чтения — не используйте его для изменения статуса.
11. website_published
Тип: Boolean. Поле, которым реально управляют публикацией: True = опубликовано, False = черновик. Именно его следует устанавливать при публикации/снятии с публикации.
12. post_date
Тип: Datetime. Дата публикации, которую видят посетители. Используется для сортировки и планирования — можно ставить будущее время для отложенных публикаций.
13. published_date
Тип: Datetime. Фактическое время публикации — проставляется автоматически в момент установки website_published в True. Полезно для аналитики.
14. active
Тип: Boolean. Флаг «мягкого удаления». При False запись архивируется и скрывается из стандартных представлений, но не удаляется физически.
15. tag_ids
Тип: Many2many (blog.tag). Теги для категоризации. Помогают фильтровать и группировать материалы; теги могут иметь структуру категорий.
16. visits
Тип: Integer. Счётчик просмотров. Только для чтения, увеличивается при открытии статьи — используется в аналитике и для выявления популярных материалов.
17. website_url
Тип: Char. Полный URL статьи на сайте. Только для чтения. Формат обычно /blog/{blog‑slug‑id}/{post‑slug‑id}.
18. cover_properties
Тип: Text. JSON‑строка с параметрами обложки: позиционирование, наложение, отображение. Используется фронтендом для рендера обложечного изображения.
19. header_visible
Тип: Boolean. Показывать ли общий хедер сайта на странице статьи — удобно при полноэкранных лендингах или встраиваемых публикациях.
20. footer_visible
Тип: Boolean. Показывать ли футер. Часто используется вместе с header_visible.
21. seo_name
Тип: Char. SEO‑френдли часть URL (slug). Определяет путь в адресе; если пусто, генерируется автоматически из заголовка.
22. website_meta_title
Тип: Char. Мета‑тег title для поисковых систем — отображается в заголовке вкладки и в результатах поисковика. Важно для SEO.
23. website_meta_description
Тип: Text. Мета‑описание для сниппета в поисковой выдаче. Рекомендуется держать в пределах 150–160 символов для корректного отображения.
24. website_meta_keywords
Тип: Char. Мета‑ключевые слова. Сейчас имеют меньшее значение для SEO, но иногда используются сторонними системами.
25. create_date
Тип: Datetime. Дата создания записи — проставляется системой автоматически. Полезна для отчётности и аудита.
26. create_uid
Тип: Many2one (res.users). Пользователь, создавший запись — автоматически проставляется, только для чтения.
27. write_date
Тип: Datetime. Дата последнего изменения — управляется системой, помогает отслеживать свежесть контента.
28. write_uid
Тип: Many2one (res.users). Последний редактор записи — только для чтения.
29. display_name
Тип: Char. Вычисляемое отображаемое имя записи — используется в выпадающих списках и результатах поиска.
30. website_id
Тип: Many2one (website). В мультисайтовых настройках указывает, к какому сайту относится публикация. По умолчанию пустая — тогда запись может показываться на всех сайтах.
Как модель используется в бизнес‑процессах
1. Контент‑маркетинг и SEO
Маркетологи создают записи blog.post для публикаций и оптимизируют их через website_meta_title, website_meta_description и seo_name. Поле content хранит сам текст и медиа, а теги помогают структурировать материалы по темам.
2. Несколько блогов на одном сайте
Компании часто ведут несколько потоков контента: новости, релизы, техническая документация. Для этого создают несколько blog.blog, а blog.post связывают через blog_id — посетители фильтруют контент по блогу и тегам.
3. Контент через API
Интеграции могут создавать и обновлять blog.post через XML‑RPC или JSON‑RPC — это удобно для миграции из других CMS, синхронизации «безголового» блога или автоматической генерации статей из внутренних систем. Odoo API поддерживает CRUD для этой модели.
4. Планируемая публикация
Задайте post_date в будущем и установите website_published = True — система покажет материал в назначенное время. Подходит для контент‑календарей и маркетинговых кампаний.
5. Коллаборация авторов
Поле author_id вместе с функционалом mail.thread даёт возможность назначать авторов, подписываться на изменения и оставлять внутренние комментарии в чаттере перед публикацией.
Как разработчики расширяют модель
Разработчики расширяют blog.post разными способами, главное — правильно работать с наследованием моделей.
Наследование моделей
Чтобы дописать функционал, создайте модель с _inherit = 'blog.post'. Так можно добавить поля, переопределить методы или ввести ограничения. Поддерживайте изменения в отдельном модуле — это упростит обновления. Не забывайте о миксинах blog.post (mail.thread, website.published.mixin) при вмешательстве в их поведение.
Добавление полей
В своём наследнике объявляйте новые поля нужного типа: Char, Many2one, Boolean, Integer, Text, Selection и т.д. Для дополнительных метаданных — например, время чтения или кастомные категории — добавьте поля и выведите их во view. Используйте префикс x_ для кастомных полей, чтобы избежать конфликтов с будущими обновлениями.
Расширения на Python
Переопределяйте методы create, write или unlink, чтобы вставить бизнес‑логику, но всегда вызывайте super(). Будьте внимательны с полями website_published и post_date — у миксина есть вычисляемые поля, и при кастомизации можно нарушить их работу. Для изменения логики генерации URL переопределяйте _compute_website_url.
Odoo Studio
Odoo Studio позволяет быстро добавить поля без кода — удобно для простых метаданных. Для сложной логики, интеграций или кастомных представлений лучше писать модуль. Модель blog.post полностью доступна через XML‑RPC и JSON‑RPC, что облегчает интеграцию.
Рекомендации по использованию
- Всегда заполняйте website_meta_title и website_meta_description — это простая и эффективная мера для повышения видимости в поиске.
- Используйте teaser_manual, когда автоматически сгенерённый анонс не отражает суть статьи — ручные превью чаще дают лучшие клики.
- Для ключевых публикаций явно указывайте seo_name и избегайте специальных символов, которые могут поломать читаемость URL.
- При публикации через API работайте с website_published — не пытайтесь править is_published, оно вычисляемое и не пригодно для записи.
- Поддерживайте единообразие тегов (tag_ids): лучше заранее создать набор меток и переиспользовать их, чтобы не размывать категорию контента.
Типичные ошибки
- Попытки записать is_published вместо website_published. is_published — поле только для чтения. Всегда изменяйте website_published для управления статусом.
- Забыть указать blog_id. Это обязательный элемент структуры: пост без привязки к блогу может не отображаться корректно на сайте.
- Оставлять website_meta_description пустым. Поисковики могут подставлять случайный фрагмент страницы — лучше задать понятное описание длиной 150–160 символов.
- Переопределять ключевые методы и не вызывать super(). Это ломает работу миксинов (публикация, чаттер) и ведёт к непредсказуемому поведению.
- Создавать одинаковые seo_name в пределах одного блога. Это приводит к конфликтам URL. Доверяйте авто‑генерации Odoo или обеспечьте уникальность самостоятельно.
Выводы
Модель blog.post — сердце блога в Odoo: она хранит текст, метаданные и состояние публикации. Понимание её полей и связей с blog.blog и blog.tag поможет настроить сайт, внедрить интеграции и правильно кастомизировать поведение.
Независимо от роли — контент‑менеджер или разработчик API — хорошее знание модели blog.post сэкономит время и предотвратит ошибки при работе с блогами.
Нужна помощь с внедрением Odoo?
Dasolo помогает компаниям внедрять, настраивать и оптимизировать Odoo. Мы специализируемся на интеграциях через API и разработке модулей, глубоко понимая архитектуру данных Odoo и модели вроде blog.post.
Если вам нужна помощь с внедрением Odoo, разработкой модулей или интеграциями — обращайтесь, мы готовы помочь. Записаться на демонстрацию чтобы обсудить ваш проект.