Как перестраивался этот блог: от Django 2.2 к Django 6

blogtest · 16.08.2026 11:32 #markdown #django #веб
Как перестраивался этот блог: от Django 2.2 к Django 6

Два года назад блог bl0g.ru работал на старом стеке WordPress-подобной связки с Django 2.2.4 и гибридной файловой системой для картинок. Этим летом я полностью переписал его — сначала как проект «с нуля на Django 6», затем полностью перенёс контент и запустил прод. В этой статье — честный разбор того, из чего блог построен сейчас и как проходил перенос.

пастельная обложка

Откуда всё взялось

Старый блог жил на Django 2.2.4 и хранил медиа в смешанном виде: filer_public с длинными UUID-путями плюс отдельный каталог обложек. Внутренняя разметка была не Markdown, а набором полу-виджетов. Переносить это «как есть» в новые модели не хотелось — решили собирать новый движок и импортировать только данные.

Итогом стало:

  • новый код на Django 6;
  • полный перенос контента (посты, пользователи, теги, изображения) через дамп;
  • обложки перерисованы под единый формат;
  • прод развёрнут на собственном сервере с автоматическим деплоем.

Архитектура

Пользователи и роли

Модель User отнаследована от Django-шного AbstractUser и дополнена ролями: admin, author, reader.

  • admin — полный доступ, админка;
  • author — может писать и публиковать статьи;
  • reader — читает и комментирует.

Плюс аватар, био и ссылка на профиль — всё хранится прямо в модели пользователя.

Статьи

Каждая статья — это:

  • Markdown-исходник (brief + content);
  • кэшированный HTML (brief_html, content_html), который пересобирается на лету при сохранении через сигнал pre_save;
  • обложка, набор тегов, статус «черновик/опубликовано»;
  • временные метки создания и изменения.

Полями HTML управляет сам движок — шаблоны никогда не гоняют Markdown повторно, поэтому страница рендерится быстро. Если меняется сам пайплайн Markdown, HTML пересобирается одной командой:

python manage.py rerender_articles

Теги, комментарии, настройки

Теги — отдельная модель с названием и слагом. Комментарии поддерживают режимы модерации «до» и «после» публикации (выбор в настройках). Настройки сайта (SiteSettings) лежат в БД: заголовок, описание, число статей на страницу, включение комментариев и регистрации, а также тема подсветки кода.

Markdown-пайплайн

Сердце блога — пайплайн на базе python-markdown и pymdown-extensions. Подключённые расширения закрывают почти любую задачу:

  • admonition — цветные заметки «Note / Tip / Warning / Danger»;
  • tabbed — вкладки с примерами кода;
  • task lists — маркированные списки с чекбоксами;
  • def_list — списки определений;
  • superfences — вложенные блоки кода и диаграммы mermaid;
  • arithmatex — формулы через MathJax;
  • magiclink, toc, attr_list, codehilite, keys, criticize — автоссылки, оглавление, атрибуты, подсветка Pygments, клавиатурные клавиши, ревью-разметка.

Пример вкладок:

def hello():
    return "Привет, мир!"
const hello = () => "Привет, мир!";

А вот заметка:

Совет

HTML пересобирается только при сохранении, поэтому правки в Markdown-исходник применяются сразу — без отдельной компиляции.

Код подсвечивается Pygments с переключаемыми темами (github, material, solarized, tango, monokai) — выбор в админке. Блоки кода автоматически оборачиваются скриптом в карточку с кнопкой «Скопировать».

Темы оформления

У блога две темы — светлая и тёмная. Переключатель хранит выбор в localStorage и ставит атрибут data-theme на <html>. Все цвета задаются CSS-переменными, поэтому смена темы происходит мгновенно, а mermaid-диаграммы перерисовываются на лету при переключении.

Прод: сервер и деплой

Прод живёт на своём сервере:

  • веб-сервер — nginx, отдаёт статику и медиа;
  • приложение — uWSGI под управлением systemd;
  • БД — PostgreSQL 16 (локально разработка идёт на SQLite — конфигурация переключается через переменные окружения);
  • HTTPS — Let's Encrypt с автообновлением сертификатов;
  • автодеплой — по пушу в основную ветку: webhook → скрипт → обновление кода, миграции, сборка статики и перезапуск.

Настройки прода читаются из файла окружения и никогда не попадают в репозиторий. Секреты — только на сервере.

Что в итоге

  • Стек стал современным и поддерживаемым: Django 6, понятная модель данных.
  • Перенос сделал контент чистым: все обложки единообразны, медиа не разбросано по UUID-каталогам.
  • Писать стало проще: Markdown с богатым пайплайном вместо виджетов старого блога.
  • Деплой — одна команда: git push в основную ветку и мониторинг логов.

Весь этот текст, включая обложку-баннер, был подготовлен автоматически — от генерации изображения до публикации. Такой workflow стал возможен благодаря набору скиллов: генерация обложек через YandexART и публикация статей напрямую в прод.

Если тебе интересно, как пишутся такие страницы или как построить подобный техпроцесс — пиши в комментариях или читай статьи про Markdown-движок в этом блоге.

Комментарии

Пока нет комментариев.

Войдите, чтобы комментировать.