Кастомні снипети Wagtail: моделі, ViewSetGroup, API

Редактори скаржаться, що кожен відгук або контакт потрібно додавати через окремі сторінки. Дерево сайту розростається, дублювання контенту неминуче — на типовому проєкті з 50 сторінками це закінчується сотнями дублів, а на великих порталах доходить до тисяч. Кастомні снипети Wagtail вирішують це: єд

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Кастомні снипети Wagtail: моделі, ViewSetGroup, API
Середній
від 1 дня до 3 днів

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

Часті запитання

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1467
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1317
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1014
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1276
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1019
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1019

Редактори скаржаться, що кожен відгук або контакт потрібно додавати через окремі сторінки. Дерево сайту розростається, дублювання контенту неминуче — на типовому проєкті з 50 сторінками це закінчується сотнями дублів, а на великих порталах доходить до тисяч. Кастомні снипети Wagtail вирішують це: єдина перевикористовувана модель даних, багаторазове використання в StreamField, швидка публікація через API. У типовому проєкті ми закладаємо 3–5 снипетів, час на створення одного — близько 2 годин. Згідно з офіційною документацією Wagtail, снипети — це перевикористовувані фрагменти контенту, не прив'язані до URL. Ми розробили понад 30 проєктів на Wagtail і гарантуємо код без N+1 запитів, з правильною індексацією та повним контролем над адмінкою. На практиці це означає, що час на внесення змін скорочується до 50%, дублі контенту знижуються на 80%, а витрати на контент — на 40–60%. На одному з проєктів ми скоротили час публікації контенту з 3 годин до 30 хвилин — у 6 разів.

Як створити снипет з нуля?

Ось покрокова інструкція, щоб додати перший снипет «Відгук»:

  1. Створіть модель у models.py з потрібними полями. Наприклад, ім'я автора, фото, текст відгуку та рейтинг.
  2. Додайте панелі для адмінки — FieldPanel, MultiFieldPanel.
  3. Зареєструйте модель через @register_snippet або SnippetViewSet (рекомендується).
  4. Використовуйте в шаблонах через SnippetChooserBlock у StreamField.

SnippetViewSet скорочує код у 3 рази та додає гнучкість. Ось приклад групування кількох снипетів:

from wagtail.snippets.views.snippets import SnippetViewSet, SnippetViewSetGroup from wagtail.snippets.models import register_snippet class TestimonialViewSet(SnippetViewSet): model = Testimonial icon = 'comment' menu_label = 'Відгуки' list_display = ['author_name', 'author_title', 'rating', 'is_featured'] list_filter = ['is_featured', 'rating'] search_fields = ['author_name', 'text'] ordering = ['-is_featured', '-id'] class TeamMemberViewSet(SnippetViewSet): model = TeamMember icon = 'user' menu_label = 'Команда' list_display = ['full_name', 'position', 'department'] list_filter = ['department'] class ContentSnippetsGroup(SnippetViewSetGroup): menu_label = 'Контент' menu_icon = 'folder-open-inverse' menu_order = 300 items = [TestimonialViewSet, TeamMemberViewSet] register_snippet(ContentSnippetsGroup) 

Чому SnippetViewSet кращий за @register_snippet?

Декоратор @register_snippet підходить для простих випадків, коли потрібно швидко додати модель у адмінку. Але коли потрібна кастомізація списку, фільтрація, пошук за кількома полями, своя іконка або групування, SnippetViewSet дає повний контроль. Він дозволяє перевизначити queryset, додати власні кнопки та дії. Різниця в продуктивності адмінки помітна при збільшенні кількості записів: SnippetViewSet використовує ті ж оптимізації, що й стандартний Pages API.

Характеристика @register_snippet SnippetViewSet
Кастомізація списку Обмежена Повний контроль
Фільтрація Тільки за замовчуванням Довільні filter_fields
Пошук Тільки по str search_fields
Іконка Немає icon
Групування Немає SnippetViewSetGroup
Продуктивність Базова Оптимізована

Як снипети економлять час редакторів?

Редактору не потрібно створювати по 20 сторінок для кожного відгуку — достатньо одного снипета, що виводиться в будь-якому місці через StreamField. Використовуйте SnippetChooserBlock:

from wagtail.snippets.blocks import SnippetChooserBlock from wagtail.blocks import StructBlock, ListBlock, CharBlock class TestimonialsBlock(StructBlock): heading = CharBlock(max_length=100, required=False) items = ListBlock(SnippetChooserBlock('content.Testimonial')) class Meta: label = 'Блок відгуків' template = 'blocks/testimonials.html' 

У шаблоні дані снипета доступні безпосередньо: {{ item.author_name }}, {{ item.text|richtext }}. Наш досвід показує, що такий підхід знижує час на внесення змін до 50%.

Глобальні налаштування через BaseSiteSetting

Частий запит — керування контактами та соцмережами з адмінки. Використовуємо BaseSiteSetting:

from wagtail.contrib.settings.models import BaseSiteSetting, register_setting @register_setting class SiteSettings(BaseSiteSetting): phone = models.CharField('Телефон', max_length=30, blank=True) email = models.EmailField('Email', blank=True) address = models.TextField('Адреса', blank=True) vk_url = models.URLField('ВКонтакте', blank=True) telegram_url = models.URLField('Telegram', blank=True) google_analytics_id = models.CharField('Google Analytics ID', max_length=20, blank=True) panels = [ MultiFieldPanel([ FieldPanel('phone'), FieldPanel('email'), FieldPanel('address'), ], heading='Контакти'), MultiFieldPanel([ FieldPanel('vk_url'), FieldPanel('telegram_url'), ], heading='Соцмережі'), FieldPanel('google_analytics_id'), ] class Meta: verbose_name = 'Налаштування сайту' 

У шаблонах використовуйте тег {% get_settings %}. Не потрібно створювати окремі сторінки або моделювати через одноразові снипети.

Коли снипет вигідніший за сторінку?

Характеристика Сторінки Снипети
URL Є Немає
Дерево сайту Беруть участь Не беруть участі
Перевикористання Через include/aside Через SnippetChooserBlock
Швидкість API ~1x ~5x швидше
Версіонування Вбудоване Через домішки
Робочі процеси Так Тільки через DraftStateMixin

Сторінки мають URL, беруть участь у дереві сайту, підтримують повноцінне версіонування та робочі процеси. Снипети не мають URL, не беруть участі в дереві, але перевикористовуються багаторазово через SnippetChooserBlock і віддаються через API. Снипети обробляються в 5 разів швидше при запиті через API, що критично для високонавантажених проєктів. Для headless-проєктів снипети легко публікуються через кастомний APIViewSet.

Типова помилка: N+1 запити при виведенні снипетів — якщо в шаблоні циклі викликати {{ item.image }} без select_related, кожен снипет зробить окремий SQL-запит. Використовуйте SnippetChooserBlock з попередньою вибіркою споріднених об'єктів через select_related у методі get_queryset ViewSet.

API для headless: швидкий старт

Зареєструйте снипет у Wagtail API:

from wagtail.api.v2.views import BaseAPIViewSet from .models import Testimonial class TestimonialsAPIViewSet(BaseAPIViewSet): model = Testimonial body_fields = BaseAPIViewSet.body_fields + [ 'author_name', 'author_title', 'text', 'rating', ] listing_default_fields = BaseAPIViewSet.listing_default_fields + [ 'author_name', 'rating', 'is_featured', ] filter_fields = ['is_featured'] api_router.register_endpoint('testimonials', TestimonialsAPIViewSet) 

Запит GET /api/v2/testimonials/?is_featured=true&order=-rating поверне JSON з потрібними полями. Ідеально для SPA або мобільного застосунку.

Що входить у роботу?

  • Код снипетів з панелями та валідацією.
  • Налаштування ViewSetGroup та кастомізація адмінки.
  • Документація по API (якщо headless).
  • Навчання редакторів роботі з контентом.
  • Гарантія відсутності N+1 запитів у шаблонах.

Зв'яжіться з нами для розробки кастомних снипетів. Отримайте готовий код снипетів з документацією та навчанням редакторів. Замовте консультацію щодо вашого проєкту — ми допоможемо підібрати оптимальне рішення.

Терміни та вартість

Терміни — від 2–3 годин на один снипет до 2–3 днів на комплект з 5–7 моделей з ViewSetGroup та API. Точну вартість розраховуємо після аналізу вашого проєкту — зв'яжіться з нами для оцінки.