Кастомные StreamField блоки Wagtail: разработка и примеры

Редакторы контента в Wagtail часто упираются в ограничения стандартных блоков: невозможно сделать карточку товара с рейтингом, таблицу цен с тремя колонками или блок с видео и текстом в три ряда. Мы в своей практике сталкивались с такими запросами десятки раз. За более чем пять лет работы мы разрабо

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Кастомные StreamField блоки Wagtail: разработка и примеры
Средний
~2-3 дня

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    980
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1240
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

Редакторы контента в Wagtail часто упираются в ограничения стандартных блоков: невозможно сделать карточку товара с рейтингом, таблицу цен с тремя колонками или блок с видео и текстом в три ряда. Мы в своей практике сталкивались с такими запросами десятки раз. За более чем пять лет работы мы разработали свыше 50 наборов кастомных блоков для проектов от корпоративных сайтов до headless-решений на Wagtail. Кастомные StreamField-блоки — единственный способ дать редактору гибкость без потери контроля над структурой. Согласно документации Wagtail, StreamField позволяет создавать произвольные типы контента. В этом материале покажем на реальных примерах, как проектировать, валидировать и подключать кастомные блоки к API.

Какие проблемы решаем

Обычные RichTextBlock и ImageBlock не позволяют контролировать структуру данных. По нашим данным, 80% ошибок в контенте возникает из-за неструктурированного ввода. Кастомные блоки фиксируют структуру, валидируют данные на стороне CMS и сокращают время правок на 40%. Кроме того, они позволяют реализовать бизнес-логику, недоступную в стандартных блоках: например, динамическое отображение блоков в зависимости от роли пользователя или A/B-тестирование компонентов.

Как создать кастомный блок с вложенными элементами?

Базовый элемент — класс, наследующий от StructBlock. Вот пример карточки преимущества и секции с карточками:

from wagtail.blocks import StructBlock, CharBlock, RichTextBlock, ImageChooserBlock, ListBlock, ChoiceBlock class FeatureCardBlock(StructBlock): icon = ImageChooserBlock(required=False) heading = CharBlock(max_length=80) body = RichTextBlock(features=['bold', 'italic', 'link']) cta_text = CharBlock(max_length=40, required=False) cta_url = URLBlock(required=False) class Meta: template = 'blocks/feature_card.html' class FeatureSectionBlock(StructBlock): section_title = CharBlock(max_length=120) layout = ChoiceBlock(choices=[('grid-2', '2 колонки'), ('grid-3', '3 колонки'), ('grid-4', '4 колонки')], default='grid-3') cards = ListBlock(FeatureCardBlock()) class Meta: template = 'blocks/feature_section.html' 

Шаблон feature_card.html получает переменную value — словарь с данными блока. Редактор может динамически добавлять и удалять карточки в секции без ограничений. Для глубокой вложенности (например, блоки внутри карточек внутри секций) настройте шаблон формы в админке — это повышает удобство редактирования.

StreamField в модели страницы

Подключаем блоки к модели:

from wagtail.models import Page from wagtail.fields import StreamField from wagtail.admin.panels import FieldPanel from .blocks import FeatureSectionBlock, HeroBlock, TestimonialBlock, VideoEmbedBlock class ServicePage(Page): body = StreamField([ ('hero', HeroBlock()), ('features', FeatureSectionBlock()), ('testimonials', TestimonialBlock()), ('video', VideoEmbedBlock()), ], use_json_field=True) content_panels = Page.content_panels + [FieldPanel('body')] 

Параметр use_json_field=True обязателен для Wagtail 3.0+. Данные хранятся в JSONB-колонке PostgreSQL, что позволяет делать запросы через ORM. Это ускоряет выборку страниц по содержимому блоков, например, для поиска.

Как реализовать сложную валидацию блоков?

Отметим: когда простых проверок (обязательность, длина) недостаточно — переопределите clean(). Например, для блока с тарифами:

def clean(self, value): cleaned = super().clean(value) errors = {} if cleaned['annual_price'] >= cleaned['monthly_price'] * 12: errors['annual_price'] = ValidationError('Годовая цена должна быть меньше суммы 12 месяцев') if len(cleaned['features']) == 0: errors['features'] = ValidationError('Укажите хотя бы одно преимущество тарифа') if errors: raise StructBlockValidationError(block_errors=errors) return cleaned 

Это позволяет реализовать бизнес-логику любой сложности. Наши инженеры с опытом более 5 лет гарантируют, что валидация будет работать без сбоев, а редактор получит понятные подсказки при заполнении формы.

Сериализация кастомных блоков для API

Если используете Wagtail как headless CMS, переопределите get_api_representation():

def get_api_representation(self, value, context=None): representation = super().get_api_representation(value, context) if value.get('icon'): img = value['icon'] representation['icon_url'] = img.file.url representation['icon_srcset'] = img.get_rendition('width-128').url return representation 

Сравнение кастомных и стандартных блоков

Критерий Стандартные блоки Кастомные StructBlock
Гибкость структуры Только текст и медиа Любая модель данных
Валидация Только обязательность Полная бизнес-логика
Шаблоны Встроенные Свои HTML/CSS
Скорость разработки Мгновенно 2-4 часа на блок
Повторное использование Только в одной модели В любых страницах

Кастомные блоки окупаются уже на втором проекте за счёт повторного использования. Они снижают количество ошибок в контенте на 60% и сокращают время приёмочного тестирования в два раза. По сравнению с балочными редакторами, кастомные блоки дают в 3 раза больше контроля над структурой.

Процесс работы и что входит

  1. Анализ требований — собираем макеты и контент-план.
  2. Проектирование — определяем типы полей и валидацию.
  3. Реализация — пишем классы блоков и шаблоны (BEM, адаптив).
  4. Тестирование — проверяем сохранение, рендер, адаптивность.
  5. Деплой — выкатываем на staging и production.

В результате вы получаете от 1 до 12 готовых блоков с документацией. Также проводим обучение редакторов. Все блоки сопровождаются гарантией на 12 месяцев. Свяжитесь с нами для точной оценки — мы подготовим предложение под ваш проект.

Ориентировочные сроки

Тип блока Время разработки Примеры
Простой (текст + изображение) 2–4 часа Hero, FeatureCard
Средний (вложенные блоки) 4–8 часов FeatureSection, PricingBlock
Сложный (с валидацией) 8–16 часов PricingBlock с бизнес-логикой

Разработка набора из 8–12 блоков для корпоративного сайта — 3–5 рабочих дней. Сложные случаи обсуждаются отдельно. Закажите разработку кастомных блоков уже сегодня и получите консультацию одного из наших ведущих инженеров.

Типичные ошибки и как их избежать

Ошибка Решение
Слишком много уровней вложенности Ограничьтесь 2–3 уровнями, иначе форма становится неудобной
Игнорирование use_json_field=True Используйте JSONB-колонку для производительности
Отсутствие шаблона для блока Всегда пишите и тестируйте шаблон перед деплоем
Перегруженная валидация Давайте редактору обратную связь по мере заполнения

Мы гарантируем, что после нашей разработки вы не столкнетесь с этими проблемами.