← На главную

В Buttondown Django почти не виден: middleware и function-based views

06.08.2026 07:34 · hackernews

Buttondown написан на Django — по скучной и показательной причине: в 2018 году автор знал именно этот стек и не хотел тратить «innovation tokens» на переключение между фреймворками. Спустя восемь лет он ни разу не пожалел о Django, хотя про выбор Vue такого не скажешь. Главное, что Django в коде почти не видно: фреймворк хорошо структурирован и просто растворяется в Python-коде и бизнес-логике.

Долгосрочную пользу приносят конкретные вещи. Middleware в Django — простые функции вокруг request/response, и это даёт огромный простор: роутинг по поддоменам, захват UTM и referrer, заголовки Content-Security-Policy, запись pageviews, контекст в структурированные логи. Например, одна middleware ставит на каждый ответ заголовок с git SHA задеплоенной сборки, чтобы залипшая вкладка браузера заметила, что вышел новый билд.

Модели в Buttondown не используют полиморфизм, зато все наследуются от BaseModel. Он добавляет UUID primary key и creation_date, а ещё прозрачно декодирует публичные id с префиксами вроде sub_ или em_ через кастомный менеджер. Плюс неявный change tracking: пишешь handle_change — метод сам вызывается, когда поле меняется. Можно замапить поле на transition table, и каждое изменение сохранится отдельной строкой. Есть хуки validate, soft delete и интеграция с проверкой целостности данных. Всё это opt-in и не требует миграций при добавлении общего функционала.

Поведение моделей вынесено в actions: на каждое действие отдельный файл с одним call(). Например, бан подписчика собирается из другого действия — end_premium_subscription.

Views строго function-based: по файлу на view, функция обязательно называется view. Никаких CBV — это снижает переключение контекста и держит представления «чистыми» в смысле функционального программирования.

Тесты крутятся на pytest и pytest-django, без factory_boy. Фикстуры самодельные, чтобы выиграть в производительности. Проверяются настоящие строки в базе, а не моки.

Сознательно выброшено: почти все сигналы (один остался для django-allauth), class-based views, классические Django apps — с ними муторно сквошить миграции, а пользы мало. Два исключения — ядро API и потенциально open-source куски. Стандартные checks тоже не используют, вместо них странные тесты. Формы Django не используют: для большинства залогиненных страниц Django рендерит тонкую оболочку и закладывает данные в json_script, а дальше Vue гидратуется из этого payload и не делает лишний API-запрос.

Читать оригинал →