/rlebe[dev].dev
sko24.kz · в проде · Петропавловск, СКО

Новость выходит — и через минуту о ней знают поисковики

Бэкенд регионального новостного издания на Django: редакция публикует материал в админке, а карты сайта, RSS, разметка для Google News и пуш-уведомления поисковикам собираются сами. Редактору остаётся писать, а не разбираться, почему статьи нет в выдаче.

3
канала пуш-индексации
4
типа карт сайта
ru / kk
полная двуязычность
48 ч
окно Google News
7
QA-проверок статьи
Точка отсчёта · июнь 2026

Издание работало. Google его почти не видел

Аудит начался с фактов, а не с ощущений: read-only проверка живого прода — robots.txt, карта сайта, RSS и сырой HTML реальной статьи. Вывод получился неприятным и очень конкретным.

◆ Было
  • В карте сайта ровно 2 URL: две страницы «О редакции». Ни одной новости.
  • News-sitemap за последние 48 часов отсутствовал — Google News нечего было забирать.
  • Никаких пушей в поисковики: свежий материал ждал, пока его найдёт краулер.
  • Готовность к Google News и Discover — 45–50% по чек-листу.
◆ Стало
  • +Индекс карт сайта: страницы, новости и полные карты статей по каждому языку с пагинацией.
  • +Google News sitemap с окном свежести 48 часов и лимитом 1000 URL — ровно по спецификации.
  • +Три канала мгновенного обнаружения: IndexNow, WebSub, каркас Google Indexing API.
  • +Редакционные QA-подсказки прямо в форме статьи — качество проверяется до публикации.
Проверяется в одну строку: sko24.kz/sitemap.xml отдаёт индекс из четырёх карт, а lastmod русской карты статей обновляется в тот же день, когда выходит материал.
Что получила редакция

Шесть вещей, которые раньше делались руками или не делались вовсе

Скорость

Публикация = сигнал поисковикам

Переход статьи в «опубликовано» ставит в очередь пинги в IndexNow и WebSub. Ни кнопки, ни ручного «отправить URL в вебмастер».

Качество

Редактор видит проблемы сразу

При сохранении статья проверяется на семь вещей: нет summary, короткий заголовок, нет обложки или она мельче, чем требует Discover, не указан источник фото, нет автора, нет даты, реклама без спонсора.

Планирование

Материал выходит сам, в 07:00

Статус «Запланировано» + дата — и Celery beat опубликует материал в срок, а затем отправит те же пинги вручную: массовый update() сигналы не поднимает, и это учтено.

Согласование

Черновик можно показать до выхода

Подписанная HMAC-ссылка на превью: главред открывает материал на сайте в реальной вёрстке, при этом статья остаётся невидимой для всех остальных.

Безопасность

Ни одна правка не теряется

django-reversion версионирует статьи вместе с переводами: любую редакцию текста можно поднять и сравнить — включая казахскую версию.

Деньги

Реклама живёт своей жизнью

Отдельный модуль баннеров: коллекции, срок показа, автоотключение по дате. Рекламу снимают без разработчика.

Что происходит после нажатия «Сохранить»

Четыре шага, из которых редакция не делает ни одного

1

Обложка приводится в порядок

Разворот по EXIF, приведение к sRGB, даунскейл до 1200×800 LANCZOS, выбор формата по наличию альфы (WEBP или прогрессивный JPEG), отдельная чёткая миниатюра 300×200 с нерезкой маской. Имена файлов — по хэшу содержимого, поэтому CDN и браузер кэшируют их вечно.

2

Кэш витрины помечается устаревшим

Не сброс по таймеру и не точечное удаление ключей, а версионирование пространств имён: счётчик articles инкрементируется — и все старые ключи перестают существовать для приложения мгновенно.

3

Поисковики получают пуш

Только при первом переходе в «опубликовано» — повторное сохранение статьи поисковики не дёргает. Три асинхронные Celery-задачи, любая ошибка логируется и не ломает сохранение материала.

4

Карты сайта уже содержат новость

Они не хранятся файлами, а строятся из БД на запрос — с conditional GET по Last-Modified и Cache-Control, чтобы краул-бюджет тратился на новое, а не на повторную выкачку старого.

→ материал доступен по API фронту на Astro и виден Google News
Под капотом

Решения, которые видно только в коде

Здесь нет ничего экзотического — есть аккуратность в местах, где проекты обычно ломаются.

поиск
Полнотекст на самом Postgres, без Elasticsearch. SearchVector с весами: заголовок A, лид B, тело C; подсветка найденного через SearchHeadline, опечатки — триграммной похожестью. Отдельный конфиг словаря на язык. Одной инфраструктурной зависимостью меньше — для регионального издания это решающий аргумент.
двуязычность
Переводы в отдельных таблицах, а не в JSON-поле. django-parler для статей, категорий, тегов и авторов; незаполненный язык просто не публикуется на этом языке, а не выдаёт пустую страницу. Карты сайта, RSS и разметка знают про оба языка по-настоящему.
запросы
Ленты собираются фабрикой queryset'ов. Один источник правды по «что считается опубликованным» — status=published и published_at <= now() — плюс готовые select_related и prefetch_related. Новая лента не приносит с собой новый N+1.
индексация
Отказ внешнего сервиса не роняет публикацию. IndexNow не ответил, хаб недоступен, credentials Google не заведены — всё это логируется и остаётся no-op. Статья выходит в любом случае.
документация
Руководство редактора лежит рядом с кодом. Разбор каждого поля формы статьи, гайд по Google News и Discover, отчёт о готовности со ссылками на строки кода. Проект передаётся вместе с ответами на вопросы, а не только с репозиторием.
Стек

Django 5.2 · DRF · Celery · PostgreSQL

Ядро
Python 3.11Django 5.2DRF 3.16Uvicorn / ASGI
Данные
PostgreSQLpsycopg 3Redisdjango-parlerdjango-mptt
Редакция
CKEditor 5django-reversiontaggit-autosuggestadmin-sortable2Pillow
Фон и SEO
Celery 5.4beatIndexNowWebSubJSON-LD
Инфраструктура
Docker ComposeNginxPoetryAstro (фронт)
Дальше

У вас есть сайт. Вопрос в том, находят ли его

Медиа, каталог, портал — разница в контенте, а механика одна: пока карта сайта пустая, разметки нет, а поисковик узнаёт о публикации через неделю, весь труд редакции работает вполсилы. Это чинится за понятный объём работ.

Аудит по фактуПроверка живого прода, а не догадки: карты, разметка, robots, сырой HTML.
ВнедрениеSEO-слой, фоновые задачи, админка под редакцию — на вашем стеке.
ПередачаДокументация и руководство для тех, кто будет работать с системой каждый день.
Обсудить проект →