CMS на Django: django CMS и Wagtail — сравнение и выбор
Какую CMS на Django выбрать: Wagtail, django CMS, Mezzanine и FeinCMS в сравнительной таблице, установка Wagtail и деревья категорий на django-mptt.
Содержание · 10 разделов
- Что такое CMS на Django и когда она нужна
- Коротко: что выбрать
- Сравнение Wagtail, django CMS, Mezzanine и FeinCMS
- Wagtail
- Минимальная установка Wagtail
- Первая модель страницы
- Wagtail как headless CMS
- Wagtail в существующем проекте
- django CMS
- Установка django CMS
- Mezzanine и FeinCMS
- Как выбрать CMS: сценарии
- django-mptt: деревья категорий
- Пример: дерево категорий на django-mptt
- Статус django-mptt
- Альтернативы django-mptt: django-treebeard и django-tree-queries
- Частые вопросы
- Wagtail — это надстройка над админкой Django?
- Можно ли сделать сайт на Wagtail без программирования?
- Есть ли в django CMS и Wagtail русский язык?
- Как перенести сайт с Mezzanine на Wagtail?
- Нужен ли django-mptt в проекте на Wagtail?
- Чем django CMS 5 отличается от 3.x из старых руководств?
- Итог
Среди CMS на Django активно развиваются две: Wagtail и django CMS. Wagtail подходит, когда типы страниц и блоки контента описывает разработчик в коде, а редакторы работают в удобной отдельной админке; у него есть встроенный REST API для headless-режима. django CMS выбирают, когда редакторы собирают страницы прямо на сайте из плагинов и важна многоязычность из коробки. Mezzanine не поддерживает Django 5.x и 6.x, FeinCMS живёт в режиме поддержки, а для новых проектов её авторы предлагают feincms3.
Ниже — сравнение по существенным критериям, сценарии выбора, установка Wagtail с первой моделью страницы и отдельный раздел про django-mptt и деревья категорий. Версии и совместимость проверены по PyPI в октябре 2026 года, установка Wagtail — на Python 3.12 и Django 6.1.
Что такое CMS на Django и когда она нужна
CMS (Content Management System, система управления контентом) — приложение, в котором редакторы без программиста создают и меняют страницы, меню, изображения и документы. CMS на Django — это набор Django-приложений: вы ставите его в обычный проект, пишете модели и шаблоны на Python и Django, а CMS даёт дерево страниц, редактор, черновики, права и медиатеку.
От WordPress такие системы отличаются тем, что сайт без программирования не собрать: типы страниц, шаблоны и блоки описывает разработчик. Зато нет ограничений плагинов — рядом с CMS работают ваши модели, личные кабинеты, API и фоновые задачи.
CMS не обязательна, если:
- контент — это записи одной-двух моделей (статьи, товары), и редакторам хватает Django Admin;
- нужно несколько статичных страниц «О компании» и «Контакты» — их закрывает встроенное приложение
django.contrib.flatpagesили обычные шаблоны; - сайт делается с нуля как учебный проект — сначала разберитесь, как сделать сайт на Django без CMS.
CMS окупается, когда страниц много, у них разная структура, редакторов несколько и нужны черновики, предпросмотр, история версий и согласование публикации.
Коротко: что выбрать
| Задача | Выбор |
|---|---|
| Контентный сайт, медиа, корпоративный сайт с типами страниц | Wagtail |
| Headless CMS для фронтенда на React, Vue или Next.js | Wagtail или django CMS 5.1+ |
| Редакторы собирают страницы на самом сайте, перетаскивая блоки | django CMS |
| Многоязычный сайт с переводом страниц | django CMS или Wagtail |
| Нужна только своя модель и админка для неё | Django Admin без CMS |
| Поддержка старого сайта на Mezzanine или FeinCMS | Миграция на Wagtail или feincms3 |
Сравнение Wagtail, django CMS, Mezzanine и FeinCMS
| Критерий | Wagtail | django CMS | Mezzanine | FeinCMS |
|---|---|---|---|---|
| Последний релиз | 8.0, август 2026 | 5.1.3, сентябрь 2026 | 6.1.1, июнь 2025 | 26.2.1, февраль 2026 |
| Статус | Активная разработка, LTS-версии | Активная разработка | Не обновляется под новые Django | Поддержка без развития, новое — в feincms3 |
| Django 6.x | 6.0 и 6.1 (с 5.2) | 6.0 и 6.1 (с 5.2) | Нет, только до 4.2 | Не заявлена, тесты до 5.2 |
| Python | 3.10–3.14 | 3.10–3.14 | 3.8–3.12 | 3.8–3.12 |
| Модель контента | Типы страниц в коде, блоки StreamField | Шаблоны с плейсхолдерами и плагины | Готовые типы страниц и блог | Типы контента, которые описывает разработчик |
| Редактор | Отдельная админка, Draftail, блоки, предпросмотр | Редактирование на странице, панель инструментов | Django Admin, TinyMCE | Django Admin |
| Headless (API) | Встроенный REST API v2, v3 в превью | Режимы headless и hybrid через djangocms-rest | Нет | Нет |
| Многоязычность | Встроенная локализация, переводы через simple_translation или wagtail-localize | Встроенная, переводы страниц | Через django-modeltranslation | Расширение translations |
| Версии и согласование | Ревизии, черновики, workflow модерации | djangocms-versioning, djangocms-moderation | Черновики | Нет |
| Дерево страниц | django-treebeard | django-treebeard | Собственное | django-mptt |
| Лицензия | BSD-3-Clause | BSD-3-Clause | BSD | BSD-3-Clause |
Обе живые CMS бесплатны и с открытым кодом, интерфейс админки в обеих переведён на русский. Wagtail выпускает новую версию примерно раз в три месяца, а каждую LTS-версию поддерживает около 18 месяцев: Wagtail 7.4 LTS (май 2026) получает исправления до ноября 2027 года и работает с Django 5.2 и 6.0.
Wagtail
Wagtail — CMS, которую в 2014 году выпустило британское агентство Torchbox. Разработчик описывает каждый тип страницы как Django-модель, наследуемую от Page: поля, разрешённых родителей и потомков, шаблон. Редактор выбирает тип, заполняет поля и публикует.
Что даёт Wagtail из коробки:
- дерево страниц с черновиками, историей ревизий, отложенной публикацией и сравнением версий;
- StreamField — контент из блоков (заголовок, текст, изображение, цитата, свой блок), которые редактор добавляет и переставляет в нужном порядке;
- Draftail — редактор форматированного текста с настраиваемым набором кнопок;
- изображения с фокусной точкой, автоматической обрезкой и форматами WebP и AVIF;
- сниппеты — переиспользуемые фрагменты вроде меню, футера и баннеров;
- workflow — цепочки согласования перед публикацией;
- несколько сайтов в одной админке, формы, редиректы, поиск, карта сайта;
- REST API для headless-режима.
Админка Wagtail — отдельный интерфейс по адресу /admin/. Стандартная админка Django в шаблоне проекта переезжает на /django-admin/ и продолжает работать для ваших обычных моделей.
Минимальная установка Wagtail
Нужен Python 3.10 или новее. Создайте виртуальное окружение и установите пакет.
Windows (PowerShell):
py -m venv .venv
.venv\Scripts\activate
pip install wagtail
macOS и Linux:
python3 -m venv .venv
source .venv/bin/activate
pip install wagtail
Wagtail подтянет совместимую версию Django. Команда wagtail start создаёт проект из шаблона:
wagtail start mysite
cd mysite
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
В requirements.txt шаблон Wagtail 8.0 записывает диапазоны версий:
Django>=6.1,<6.2
wagtail>=8.0,<8.1
После запуска сервера откройте http://127.0.0.1:8000/ — там приветственная страница Wagtail. Админка находится по адресу http://127.0.0.1:8000/admin/, войдите под пользователем из createsuperuser. Подробнее о создании администратора — в статье о createsuperuser.
Шаблон создаёт три приложения и разделённые настройки:
mysite/
home/ # модель HomePage и главная страница
search/ # поиск по сайту
mysite/
settings/ # base.py, dev.py, production.py
templates/
urls.py
Dockerfile
manage.py
requirements.txt
Чтобы админка была на русском, поменяйте язык в mysite/settings/base.py:
LANGUAGE_CODE = "ru"
Каждый пользователь может выбрать язык интерфейса и в своём профиле в админке.
Первая модель страницы
Добавим тип страницы «Статья» с вступлением и телом из блоков. Код — в home/models.py:
from wagtail import blocks
from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField, StreamField
from wagtail.images.blocks import ImageBlock
from wagtail.models import Page
class HomePage(Page):
pass
class ArticlePage(Page):
intro = RichTextField(blank=True)
body = StreamField(
[
("heading", blocks.CharBlock(form_classname="title")),
("paragraph", blocks.RichTextBlock()),
("image", ImageBlock()),
],
blank=True,
)
content_panels = Page.content_panels + [
FieldPanel("intro"),
FieldPanel("body"),
]
# Статью можно создать только внутри главной страницы
parent_page_types = ["home.HomePage"]
Шаблон ищется по имени модели — home/templates/home/article_page.html:
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block content %}
<h1>{{ page.title }}</h1>
{{ page.intro|richtext }}
{% include_block page.body %}
{% endblock %}
Создайте и примените миграции:
python manage.py makemigrations home
python manage.py migrate
Migrations for 'home':
home\migrations\0003_articlepage.py
+ Create model ArticlePage
Теперь в админке у главной страницы появится кнопка добавления дочерней страницы типа Article page. Страницы можно создавать и из кода — например, при импорте старого сайта:
from home.models import ArticlePage, HomePage
home = HomePage.objects.get(slug="home")
article = ArticlePage(title="Первая статья", slug="first", intro="<p>Привет!</p>")
home.add_child(instance=article)
article.save_revision().publish()
print(article.url) # → /first/
print(article.path, article.depth) # → 000100010001 3
Поля path и depth хранит django-treebeard — о нём ниже, в разделе про деревья.
Wagtail как headless CMS
Встроенный API v2 отдаёт страницы, изображения и документы в JSON. Подключите приложения в INSTALLED_APPS:
INSTALLED_APPS = [
# ...
"wagtail.api.v2",
"rest_framework",
]
Создайте роутер в mysite/api.py:
from wagtail.api.v2.router import WagtailAPIRouter
from wagtail.api.v2.views import PagesAPIViewSet
api_router = WagtailAPIRouter("wagtailapi")
api_router.register_endpoint("pages", PagesAPIViewSet)
Подключите его в urls.py перед строкой path("", include(wagtail_urls)):
from .api import api_router
urlpatterns = [
# ...
path("api/v2/", api_router.urls),
]
Поля модели попадают в API только через api_fields:
from wagtail.api import APIField
class ArticlePage(Page):
# ...поля и панели из примера выше
api_fields = [APIField("intro"), APIField("body")]
Запрос /api/v2/pages/?type=home.ArticlePage&fields=intro вернёт:
{
"meta": {
"total_count": 1
},
"items": [
{
"id": 4,
"meta": {
"type": "home.ArticlePage",
"detail_url": "http://localhost/api/v2/pages/4/",
"html_url": "http://localhost/first/",
"slug": "first",
"first_published_at": "2026-10-10T00:22:47.451056Z"
},
"title": "Первая статья",
"intro": "<p>Привет!</p>"
}
]
}
API v2 построен на Django REST Framework. В Wagtail 8.0 появилось превью API v3 на Django Ninja с типизацией; пока оно может меняться без обратной совместимости, поэтому в продакшне используйте v2. Для GraphQL есть сторонний пакет wagtail-grapple.
Wagtail в существующем проекте
Wagtail можно добавить в готовый Django-проект без wagtail start: перечислить приложения wagtail.*, modelcluster и taggit в INSTALLED_APPS, добавить wagtail.contrib.redirects.middleware.RedirectMiddleware, задать WAGTAIL_SITE_NAME, WAGTAILADMIN_BASE_URL, MEDIA_ROOT и MEDIA_URL, подключить URL админки и wagtail_urls последним маршрутом. Ваши модели и представления продолжат работать как раньше, а маршруты, которые не совпали с ними, обработает дерево страниц.
django CMS
django CMS — одна из старейших CMS на Django, её развивает некоммерческая ассоциация django CMS Association. Главное отличие от Wagtail — редактирование прямо на странице сайта. Редактор входит на сайт, включает режим редактирования на панели инструментов вверху и добавляет плагины (текст, изображение, кнопку, сетку Bootstrap) в плейсхолдеры — области, которые разработчик отметил в шаблоне.
Возможности:
- дерево страниц с ЧПУ, меню и несколькими сайтами;
- многоязычность из коробки: у каждой страницы есть версии на разных языках;
- плагины — переиспользуемые компоненты; свой плагин пишется как небольшой Django-класс с шаблоном;
- apphooks — подключение ваших Django-приложений (каталог, блог) к странице дерева;
- версии и согласование через официальные дополнения djangocms-versioning и djangocms-moderation;
- текстовый редактор djangocms-text: по умолчанию TipTap, можно переключить на CKEditor 4 или 5;
- headless-режимы с версии 5.1:
traditional(HTML-страницы),headless(только API через djangocms-rest) иhybrid(оба варианта).
Цена такого подхода — более высокий порог входа: редакторам нужно понять плейсхолдеры, режим структуры и плагины, а разработчику — их взаимодействие с шаблонами.
Установка django CMS
С пакетом django-cms ставится команда djangocms. Она создаёт проект из официального шаблона, устанавливает зависимости, применяет миграции и предлагает создать суперпользователя:
pip install django-cms
djangocms mysite
cd mysite
python manage.py runserver
Режим и дополнения задаются флагами: --mode headless, --mode hybrid, --no-versioning, --moderation. Чтобы добавить django CMS в существующий проект, передайте точку вместо имени. Флаг --dry-run покажет изменения в settings.py и urls.py, ничего не меняя:
djangocms . --dry-run
Команды python manage.py cms install в django CMS нет. Инструкции с ней относятся к устаревшим версиям или ошибочны. Для проверки установки служит python manage.py cms check.
Mezzanine и FeinCMS
Mezzanine — CMS «всё в одном» с блогом, страницами, формами и магазином через расширение. Последний релиз 6.1.1 вышел в июне 2025 года и требует Django ниже 5.0, поэтому с Django 5.2 LTS и 6.x он не установится. Сайт проекта перенаправляет на репозиторий Mezzanine на GitHub. Для нового проекта Mezzanine не подходит; существующий сайт лучше планово перенести на Wagtail.
FeinCMS — конструктор CMS: разработчик описывает типы контента, а страница собирается из их экземпляров в админке Django. Пакет обновляется (26.2.1, февраль 2026), но тесты в репозитории идут до Django 5.2, и авторы прямо советуют новым проектам feincms3. Это набор инструментов для своей CMS: он поддерживает Django 6.0 и Python 3.14 и хранит дерево страниц через django-tree-queries вместо django-mptt.
Среди других вариантов встречается CodeRed CMS — надстройка над Wagtail с готовыми блоками для маркетинговых сайтов. Версия 6.0 работает только с Wagtail 7.x и Django до 5.2, поэтому она отстаёт от актуального Wagtail.
Как выбрать CMS: сценарии
- Новостной или корпоративный сайт, блог, база знаний. Wagtail: типизированные страницы, StreamField, workflow и удобная для редакторов админка.
- Фронтенд на React, Vue или Next.js. Wagtail с API v2 — проверенный вариант; django CMS 5.1 с режимом
headlessподойдёт, если команде нужна именно его модель плагинов. - Маркетологи сами собирают лендинги. django CMS: визуальная сборка страницы из плагинов на самом сайте.
- Сайт на нескольких языках. django CMS — многоязычность заложена в модель страниц. Wagtail справляется не хуже, но перевод включается настройками
WAGTAIL_I18N_ENABLEDиWAGTAIL_CONTENT_LANGUAGESи приложением simple_translation или пакетом wagtail-localize. - Интернет-магазин. CMS отвечает за контентные страницы. Каталог, корзину и оплату пишут отдельными Django-приложениями или берут специализированные решения вроде django-oscar и Saleor, а CMS подключают для статей и лендингов.
- Внутренний инструмент, CRM, кабинет. CMS не нужна — хватит своих моделей и Django Admin.
Перед выбором учтите хостинг. Любой CMS на Django нужен сервер с Python — VPS или PaaS; обычный PHP-хостинг не подойдёт. Приложение запускают через Gunicorn или Uvicorn за Nginx, как описано в статье о деплое Django.
django-mptt: деревья категорий
django-mptt — библиотека для хранения деревьев в реляционной базе по алгоритму MPTT (Modified Preorder Tree Traversal, модифицированный обход дерева в прямом порядке, он же «вложенные множества»). Её используют для деревьев категорий каталога, многоуровневых меню, рубрик и комментариев. Запросы «все потомки категории» и «путь от корня» выполняются одним SQL-запросом без рекурсии.
Каждая строка хранит четыре служебных поля:
lftиrght— границы узла при обходе дерева; все потомки лежат между ними;level— глубина (у корня 0);tree_id— номер дерева, если корней несколько.
Цена быстрых чтений — дорогая запись: вставка или перенос узла пересчитывает lft и rght у многих строк.
Пример: дерево категорий на django-mptt
pip install django-mptt
Добавьте "mptt" в INSTALLED_APPS и унаследуйте модель от MPTTModel:
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
class Category(MPTTModel):
name = models.CharField(max_length=100)
parent = TreeForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="children",
)
class MPTTMeta:
order_insertion_by = ["name"]
def __str__(self):
return self.name
Связь с родителем — тот же ForeignKey на свою модель, подробнее о связях — в статье про ForeignKey в Django. Служебные поля django-mptt добавит сам при makemigrations.
electronics = Category.objects.create(name="Электроника")
phones = Category.objects.create(name="Смартфоны", parent=electronics)
Category.objects.create(name="Android", parent=phones)
Category.objects.create(name="iPhone", parent=phones)
Category.objects.create(name="Ноутбуки", parent=electronics)
phones.refresh_from_db()
print(list(electronics.get_descendants()))
print(list(phones.get_ancestors(include_self=True)))
print(phones.lft, phones.rght, phones.level, phones.tree_id)
[<Category: Ноутбуки>, <Category: Смартфоны>, <Category: Android>, <Category: iPhone>]
[<Category: Электроника>, <Category: Смартфоны>]
4 9 1 1
refresh_from_db() нужен потому, что после добавления потомков значения lft и rght в базе изменились, а объект в памяти остался со старыми.
Для админки есть DraggableMPTTAdmin — список с отступами и перетаскиванием узлов:
from django.contrib import admin
from mptt.admin import DraggableMPTTAdmin
from .models import Category
@admin.register(Category)
class CategoryAdmin(DraggableMPTTAdmin):
list_display = ["tree_actions", "indented_title"]
list_display_links = ["indented_title"]
Многоуровневое меню в шаблоне выводит тег recursetree:
{% load mptt_tags %}
<ul>
{% recursetree nodes %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul>{{ children }}</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
В контекст передайте Category.objects.all() под именем nodes; children внутри тега — уже отрисованные дочерние узлы.
Статус django-mptt
В репозитории django-mptt проект помечен как неподдерживаемый: ошибки исправляют по мере сил, совместимость с новыми Django сохраняют, новых функций не будет. Авторы объясняют это устройством MPTT: при одновременной записи дерево может повредиться, а bulk_create, bulk_update, сырой SQL и миграции данных обходят пересчёт полей. Восстанавливает дерево метод Category.objects.rebuild(), но он блокирует таблицу.
По PyPI на октябрь 2026 года:
- стабильная версия 0.18.0 (август 2025) заявляет Django 4.2–5.2 и Python 3.9–3.13;
- поддержка Django 6.0 есть в предрелизе 0.19rc1 (июнь 2026);
- на Django 6.1 версия 0.18.0 в нашей проверке создала дерево и выполнила запросы из примера выше, но официально эта связка не заявлена.
Для существующего проекта django-mptt по-прежнему рабочий вариант. Для нового дерева авторы библиотеки советуют альтернативы.
Альтернативы django-mptt: django-treebeard и django-tree-queries
| Библиотека | Способ хранения | Django 6.x | Кто использует | Когда выбирать |
|---|---|---|---|---|
| django-mptt | Вложенные множества (lft, rght) | 6.0 в 0.19rc1 | FeinCMS, старые проекты | Уже стоит в проекте, дерево редко меняется |
| django-treebeard | Материализованный путь, вложенные множества или список смежности | 6.0 и 6.1 (7.0) | Wagtail, django CMS | Большие деревья, быстрые выборки поддеревьев |
| django-tree-queries | Только parent, дерево считается рекурсивным CTE | Тесты на 6.0 и 6.1 | feincms3 | Простая модель, частые изменения |
django-treebeard предлагает три реализации: MP_Node (materialized path — материализованный путь, строка вида 00010002), NS_Node (вложенные множества, как MPTT) и AL_Node (список смежности). На MP_Node построены деревья страниц Wagtail и django CMS. С версии 6.0 методы работы с деревом переехали с модели в менеджер: node.get_children() превратился в Model.objects.get_children(node). Старые вызовы работают с предупреждением RemovedInTreebeard8Warning и будут удалены в версии 8.
from django.db import models
from treebeard.mp_tree import MP_Node
class Section(MP_Node):
name = models.CharField(max_length=100)
node_order_by = ["name"]
def __str__(self):
return self.name
root = Section.objects.add_root(instance=Section(name="Электроника"))
phones = Section.objects.add_child(root, instance=Section(name="Смартфоны"))
Section.objects.add_child(phones, instance=Section(name="Android"))
Section.objects.add_child(root, instance=Section(name="Ноутбуки"))
for node, info in Section.objects.get_annotated_list():
print(" " * info["level"] + node.name)
Электроника
Ноутбуки
Смартфоны
Android
Для админки treebeard есть TreeAdmin с формой movenodeform_factory(Section).
Важно: Wagtail 8.0 и django CMS 5.1 требуют django-treebeard версии ниже 6.0 и ставят 5.3.x. Если в проекте с Wagtail нужна своя древовидная модель на treebeard, пишите код в стиле 5.x (методы на экземпляре:
root.add_child(...)) или дождитесь, пока CMS обновит зависимость.
django-tree-queries хранит только поле parent, а глубину и путь вычисляет рекурсивным запросом (CTE, Common Table Expression) в момент выборки. Писать в такое дерево дёшево — меняется одна строка, а рассинхронизация служебных полей невозможна:
from django.db import models
from tree_queries.models import TreeNode
class Rubric(TreeNode):
name = models.CharField(max_length=100)
root = Rubric.objects.create(name="Электроника")
phones = Rubric.objects.create(name="Смартфоны", parent=root)
Rubric.objects.create(name="Android", parent=phones)
for node in Rubric.objects.with_tree_fields():
print(node.name, node.tree_depth, node.tree_path)
Электроника 0 [1]
Смартфоны 1 [1, 2]
Android 2 [1, 2, 3]
Библиотека работает с PostgreSQL, SQLite, MariaDB 10.2.2+ и MySQL 8; на MySQL и MariaDB глубина дерева ограничена 50 уровнями. Для небольших деревьев (меню на десяток пунктов) хватает обычного ForeignKey("self") и выборки всех строк одним запросом — без сторонних библиотек.
Частые вопросы
Wagtail — это надстройка над админкой Django?
Нет. У Wagtail собственный интерфейс по адресу /admin/ со своим деревом страниц, медиатекой и правами. Стандартная админка Django остаётся доступной на /django-admin/ и подходит для ваших моделей, которые не являются страницами. Модели можно показать и в админке Wagtail через сниппеты.
Можно ли сделать сайт на Wagtail без программирования?
Нет. Wagtail и django CMS рассчитаны на команду, где разработчик описывает типы страниц, блоки и шаблоны, а редакторы наполняют сайт. Если программиста нет и нужен типовой сайт, проще взять конструктор или PHP-CMS.
Есть ли в django CMS и Wagtail русский язык?
Да, интерфейс админки обеих систем переведён на русский. Он включается настройкой LANGUAGE_CODE = "ru" или выбором языка в профиле пользователя. Официальная документация обеих CMS — на английском; русский перевод документации django CMS, который встречается в поиске, сделан для устаревшей версии 3.9.
Как перенести сайт с Mezzanine на Wagtail?
Автоматического конвертера нет. Опишите в Wagtail типы страниц, соответствующие страницам Mezzanine, и напишите management-команду, которая читает старые записи и создаёт страницы через parent.add_child(instance=...) и save_revision().publish(), как в примере выше. Изображения переносятся через модель wagtail.images.models.Image, старые адреса — через приложение редиректов wagtail.contrib.redirects.
Нужен ли django-mptt в проекте на Wagtail?
Для страниц — нет: дерево страниц Wagtail уже хранится в django-treebeard. Для отдельного дерева категорий товаров или рубрик выбирайте между treebeard в стиле 5.x (он уже установлен вместе с Wagtail) и django-tree-queries. Ставить django-mptt третьей библиотекой деревьев для нового кода нет смысла.
Чем django CMS 5 отличается от 3.x из старых руководств?
С ветки 4.x содержимое страниц хранится отдельно от дерева и поддерживает версии через djangocms-versioning. В актуальных версиях проект создаётся командой djangocms, текстовый редактор — djangocms-text, а с 5.1 появились headless-режимы. Настройки и плагины из руководств по 3.x часто не подходят без изменений.
Итог
- Для нового контентного сайта на Django начинайте с Wagtail: типы страниц в коде, StreamField, удобная админка, встроенный REST API и LTS-версии с поддержкой Django 5.2 и 6.x.
- django CMS выбирайте, когда редакторы собирают страницы визуально на сайте и важна многоязычность; с версии 5.1 он умеет работать и headless.
- Mezzanine несовместим с актуальными Django, FeinCMS только поддерживается — для новых проектов используйте Wagtail или feincms3.
- django-mptt работает и подходит для существующих деревьев категорий, но официально не развивается. Для нового кода берите django-treebeard (на нём построены Wagtail и django CMS) или django-tree-queries.
Если вы только знакомитесь с фреймворком, начните с обзора Django для начинающих, а к CMS переходите, когда освоите модели, шаблоны и админку.
- #Django
- #Wagtail
- #django CMS
- #CMS
- #django-mptt