Введение

Что такое FastFort, что он даёт проекту на FastAPI при установке, и ограничения, при которых он создавался.

Доступно с версии v0.1.0

FastFort — это фреймворк админки и аутентификации для FastAPI. Он даёт проекту то, что есть в Django, но чего нет в FastAPI: админку моделей, сессии и JWT, роли, журнал аудита — всё это устанавливается одним wheel-пакетом.

uv add "fastfort[sqlalchemy,postgres]"

Больше ничего не нужно. Никакого Node.js, никакой сборки, никакого CDN, никакого генератора кода, который пишет файлы, которые потом приходится читать.

Что вы получаете после установки

Зарегистрируйте модель и откройте /admin:

from fastfort import admin

from app.models import Product


@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "category", "price", "stock", "is_active")
    list_filter = ("is_active", "category", "price")
    search_fields = ("sku", "name", "description")
    ordering = ("-created_at",)
    select_related = ("category",)

В результате получается таблица с сортируемыми столбцами, полем поиска, панелью фильтров, постраничной навигацией, выбором строк для массовых действий и рабочими страницами создания, редактирования и удаления. Внешние ключи превращаются в удобные для поиска селекторы — с поддержкой автодополнения через отдельный endpoint, как только целевая таблица перерастает выпадающий список, — а поля многие-ко-многим становятся удаляемыми чипами.

Каждый из этих элементов управления работает при отключённом JavaScript. Сортировка — это ссылка, фильтрация — это форма, а скрипт на стороне браузера лишь улучшает их на месте, а не подменяет собой.

Ограничения, при которых он создавался

Это не предпочтения. Каждое из них закрывает целый класс проблем, и набор тестов падает, если хоть одно нарушено.

Node.js — нигде

CSS, JavaScript, иконки и шаблоны админки — это написанные вручную файлы, которые отдаются прямо из пакета. Проект устанавливает один wheel-пакет и получает рабочую админку. В развёртывании FastFort нет npm install, в Docker-образе нет node_modules, а страница, показывающая ваши данные, не делает запросов к CDN.

У фронтенда есть бюджет размера, соблюдение которого проверяется тестом — сейчас это 24 КБ CSS и 29 КБ скрипта в сжатом виде (gzip). Увеличивать бюджет допустимо, и это уже происходило трижды; каждое увеличение сопровождается указанием функции, которая его вызвала.

Админка никогда не видит вашу ORM

Ничто выше fastfort/orm/ не имеет права импортировать SQLAlchemy или Tortoise, и при нарушении этого правила тест валит сборку. Интроспекция превращает модель в ModelSpec — простые, неизменяемые, сериализуемые в JSON данные, — и все вышестоящие слои работают именно с ними.

Результат оказался вполне конкретным: второй адаптер ORM был добавлен без изменения хотя бы одной строки в админке, а набор тестов на соответствие задаёт обоим бэкендам одни и те же вопросы над одинаковыми формами моделей — так что утверждение «второй ведёт себя так же» становится тестом, а не декларацией.

Ошибки конфигурации проявляются при запуске

Опечатка в list_display — это не ошибка 500 при первом открытии страницы кем-то. Это ошибка запуска, называющая сразу все проблемы:

ConfigurationError: ProductAdmin is misconfigured:
  - list_display names 'pirce', which shop.product has no
  - list_filter names 'description'; free-text and multi-valued fields
    cannot be offered as a filter
  - ordering names 'rank', which is not sortable
Hint: Fields available on shop.product: category, cost, created_at, ...

У массового присваивания только одна точка контроля

FieldSpec.editable — единственный источник истины. Отправленное значение для поля, чья спецификация указывает editable=False, отбрасывается — независимо от того, через какую форму или endpoint оно пришло. Второго флага, который мог бы ему противоречить, намеренно не существует.

Адаптеры никогда не коммитят

Они делают flush. Контекстный менеджер UnitOfWork коммитит при штатном выходе и откатывает изменения при исключении, поэтому наполовину неудавшийся запрос не оставляет после себя ничего — включая массовое действие, которое падает на сороковой строке.

Чем он не является

  • Не CMS. Он редактирует строки в ваших таблицах. У него нет собственной модели контента, дерева страниц или workflow публикации.
  • Не REST-фреймворк. Это админка. Ваш API остаётся вашим; FastFort монтируется под одним URL-префиксом и не выходит за его пределы.
  • Пока не стабилен. 0.3.0 — это версия до 1.0, и публичный API ещё не зафиксирован. Минорный релиз может содержать обратно несовместимые изменения — каждое из них перечислено под заголовком Breaking в changelog. Фиксируйте версию.

Куда двигаться дальше