Настройка Wagtail API для Headless-режима

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка Wagtail API для Headless-режима
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Настройка Wagtail API для Headless-режима

Wagtail API v2 — встроенный REST API только для чтения. Для полноценного headless с мутациями используют Strawberry Django или django-graphene в связке.

Включение Wagtail API

# settings/base.py
INSTALLED_APPS += ['wagtail.api.v2']

# urls.py
from wagtail.api.v2.views import PagesAPIViewSet
from wagtail.api.v2.router import WagtailAPIRouter
from wagtail.images.api.v2.views import ImagesAPIViewSet
from wagtail.documents.api.v2.views import DocumentsAPIViewSet

api_router = WagtailAPIRouter('wagtailapi')
api_router.register_endpoint('pages',     PagesAPIViewSet)
api_router.register_endpoint('images',    ImagesAPIViewSet)
api_router.register_endpoint('documents', DocumentsAPIViewSet)

urlpatterns = [
    path('api/v2/', api_router.urls),
    path('',        include(wagtail_urls)),
]

Кастомизация API ViewSet

# blog/api.py
from wagtail.api.v2.views import PagesAPIViewSet
from wagtail.api.v2.filters import FieldsFilter, OrderingFilter, SearchFilter

class BlogPostAPIViewSet(PagesAPIViewSet):
    # Разрешённые поля для фильтрации
    filter_backends = [FieldsFilter, OrderingFilter, SearchFilter]

    # Поля доступные через API
    body_fields = PagesAPIViewSet.body_fields + [
        'intro', 'date', 'tags', 'categories',
    ]
    meta_fields  = PagesAPIViewSet.meta_fields + [
        'first_published_at',
    ]
    listing_default_fields = PagesAPIViewSet.listing_default_fields + [
        'intro', 'date',
    ]

    def get_queryset(self):
        return BlogPost.objects.live().public()


# Регистрация кастомного endpoint
api_router.register_endpoint('blog-posts', BlogPostAPIViewSet)

Запросы к API

const BASE = process.env.WAGTAIL_URL;

// Список страниц определённого типа
const res = await fetch(
  `${BASE}/api/v2/pages/?type=blog.BlogPost&fields=title,intro,date,slug,first_published_at,thumbnail&order=-first_published_at&limit=12`
);
const { items, meta } = await res.json();

// Одна страница по slug
const post = await fetch(
  `${BASE}/api/v2/pages/?slug=my-post-slug&type=blog.BlogPost&fields=*`
).then(r => r.json()).then(r => r.items[0]);

// Поиск
const results = await fetch(
  `${BASE}/api/v2/pages/?search=wagtail+tutorial&type=blog.BlogPost`
);

// Preview (требует отдельный PreviewAPIViewSet)
const preview = await fetch(`${BASE}/api/v2/pages/preview/?content_type=blog.blogpost&token=${previewToken}`);

API Images с трансформациями

Wagtail API возвращает URL изображений без трансформаций. Для получения rendition нужно кастомное поле:

from wagtail.api.v2.serializers import PageSerializer
from wagtail.images.shortcuts import get_rendition_or_not_found
from rest_framework import serializers

class BlogPostSerializer(PageSerializer):
    thumbnail = serializers.SerializerMethodField()

    def get_thumbnail(self, obj):
        if not obj.header_image:
            return None
        rendition = get_rendition_or_not_found(obj.header_image, 'fill-800x400-c100')
        return {
            'url':    rendition.url,
            'width':  rendition.width,
            'height': rendition.height,
            'alt':    obj.header_image.alt_text,
        }

class BlogPostAPIViewSet(PagesAPIViewSet):
    serializer_class = BlogPostSerializer

Next.js ISR + Wagtail Webhooks

Wagtail не имеет встроенных webhooks. Реализуем через сигналы Django:

# blog/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from wagtail.signals import page_published, page_unpublished
import httpx

@receiver(page_published)
def on_page_published(sender, instance, **kwargs):
    if not hasattr(instance, 'slug'):
        return
    try:
        httpx.post(
            settings.NEXTJS_REVALIDATE_URL,
            json={'slug': instance.slug, 'type': instance.__class__.__name__},
            headers={'x-revalidate-secret': settings.NEXTJS_REVALIDATE_SECRET},
            timeout=5.0,
        )
    except Exception:
        pass
// Next.js: app/api/revalidate/route.ts
export async function POST(request: Request) {
  const { slug, type } = await request.json();
  if (type === 'BlogPost') {
    revalidatePath(`/blog/${slug}`);
    revalidatePath('/blog');
  }
  return Response.json({ revalidated: true });
}

Полная настройка Wagtail API с Next.js — 2–4 дня.