Машинный перевод под контролем человека
Этот контент переведён с помощью машинной генерации, направляемой составленными людьми глоссариями и руководствами по стилю. Поскольку текст не проверяется вручную построчно, возможны отдельные ошибки или неестественные формулировки.
В случае любых расхождений авторитетным источником считается оригинальная версия на английском языке.
Переход с Django Admin
Если вы знакомы с Django Admin, starlette-admin покажется вам привычным инструментом. Оба решения генерируют административный интерфейс на основе декларативной конфигурации для каждой модели, а также поддерживают инлайн-редактирование, пакетные действия и разрешения на уровне каждого запроса.
Различия носят структурный характер. starlette-admin работает поверх любого ASGI-приложения вместо обязательного использования Django, поддерживает несколько ORM и позволяет подключить собственную аутентификацию, не навязывая встроенную модель пользователя.
В этом руководстве каждая основная концепция ModelAdmin сопоставлена со своим эквивалентом в starlette-admin, с примерами кода рядом.
Концептуальная модель
| Концепция Django Admin | Эквивалент в starlette-admin |
|---|---|
AdminSite |
экземпляр Admin, подключённый к вашему приложению |
ModelAdmin |
подкласс ModelView |
admin.site.register(Model, ModelAdmin) |
admin.add_view(MyView(Model)) |
admin.site.urls в urlpatterns |
admin.mount_to(app) |
| Django ORM | SQLAlchemy, SQLModel, MongoEngine, Beanie или Tortoise ORM через starlette_admin.contrib.* |
__str__ на модели |
__admin_repr__(self, request) — асинхронный метод, учитывающий запрос |
| Поля формы, выводимые из полей модели | Поля, выводимые конвертером backend'а, с возможностью настройки для каждого поля |
Регистрация модели
from starlette_admin.contrib.sqla import Admin, ModelView
class PostView(ModelView):
fields = ["id", "title", "content", "published", "created_at"]
exclude_fields_from_list = ["content"]
searchable_fields = ["title", "content"]
admin = Admin(engine, title="Blog Admin", secret_key="change-me")
admin.add_view(PostView(Post, icon="fa fa-newspaper"))
admin.mount_to(app) # app is your FastAPI or Starlette instance
Обратите внимание на два структурных отличия:
- Один список полей управляет всеми страницами. Атрибут
fields— единственный источник истины. Для вариаций по страницам используютсяexclude_fields_from_list,exclude_fields_from_detail,exclude_fields_from_createиexclude_fields_from_edit. - Экземпляр
Adminвладеет движком базы данных. Вам не нужно передавать сессию каждому представлению.
Настройки страницы списка
| Django Admin | starlette-admin | Примечания |
|---|---|---|
list_display |
fields минус exclude_fields_from_list |
Один список полей управляет всеми страницами. |
list_display с callable или @admin.display |
ComputedField либо getter= у любого поля |
Например, ComputedField("full_name", getter=lambda request, obj: ...). Используйте getter= у типизированного поля, например поля даты или изображения, чтобы сохранить его способ отображения. |
| Переформатирование реального столбца для отображения | formatter= у поля |
Это dict[RequestAction, callable], поэтому список, детальная страница и экспорт могут форматировать данные по-разному. В Django требуется callable плюс admin_order_field, чтобы сохранить сортировку; здесь столбец остаётся сортируемым. |
search_fields |
searchable_fields |
Обеспечивает как полнотекстовый поиск, так и конструктор фильтров. |
list_filter |
searchable_fields в сочетании с filters= для каждого поля |
Пользователи получают визуальный конструктор с вложенными группами AND/OR вместо фиксированной боковой панели. См. раздел Фильтры. |
ordering |
fields_default_sort |
Например, fields_default_sort = [("created_at", True)] выполняет сортировку по убыванию. |
admin_order_field / возможность сортировки |
sortable_fields |
По умолчанию каждое поле можно сортировать. |
list_editable |
inline_editable_fields |
Пользователи выделяют ячейку и редактируют её прямо на месте. |
list_per_page |
page_size, page_size_options |
Управляет ограничениями пагинации. |
date_hierarchy |
Фильтры по датам, такие как between и in the past |
Отдельной панели drill-down нет; этот сценарий покрывается конструктором фильтров. |
empty_value_display |
Запись formatter= или null_template |
Formatter'ы получают значения None, поэтому могут подставлять заполнитель. null_template заменяет сам отрисованный HTML-код. |
Формы
| Django Admin | starlette-admin | Примечания |
|---|---|---|
fields / exclude |
fields, exclude_fields_from_create, exclude_fields_from_edit |
Управляют видимостью полей формы. |
fieldsets |
form_layout |
Свободная компоновка с помощью FieldsetWidget, TabsWidget, GridWidget и RowWidget. |
readonly_fields |
read_only=True у поля |
Поле также можно исключить из представлений создания и редактирования. |
prepopulated_fields |
SlugField("slug", populate_from="title") |
То же поведение живой slug-генерации. |
autocomplete_fields, raw_id_fields |
Стандартное поведение HasOne / HasMany |
Виджеты отношений — это Select2-поля с серверным поиском «из коробки». |
filter_horizontal / filter_vertical |
HasMany |
Отображается как компонент множественного выбора с поиском. |
formfield_overrides |
Явные записи в списке fields |
Заменяет автоматически определённое поле напрямую: fields = ["id", TextAreaField("bio")] |
| Кастомная валидация формы | Field validators= или FormValidationError в hook'ах |
См. Валидаторы. |
Form field to_python() / кастомное приведение типов |
parser= у поля |
Заменяет стандартное парсинг-поведение поля при отправке форм или импорте для конкретного RequestAction. |
| Help text поля модели | help_text= |
Доступно в любом определении поля. |
Пример fieldsets
Возможности form_layout шире, чем у fieldsets: можно создавать вкладки, адаптивные сетки и вложенные макеты. См. Form Layout.
Инлайны
starlette-admin определяет внешний ключ автоматически, если он однозначен, и поддерживает составные внешние ключи. Расширенные конфигурации описаны в разделе Inline Forms.
Действия
from starlette_admin import ActionSelection, action, flash
class ArticleView(ModelView):
actions = ["make_published", "delete"]
@action(
name="make_published",
text="Mark selected articles as published",
confirmation="Publish the selected articles?",
)
async def make_published(
self, request: Request, selection: ActionSelection
) -> None:
for article in await selection.rows():
article.published = True
flash(request, "Articles published")
Там, где Django Admin передаёт QuerySet, обработчик starlette-admin получает объект ActionSelection. Он лениво разрешает строки, первичные ключи и активные фильтры и ведёт себя одинаково, когда пользователь выбирает все совпадающие записи.
Действия также могут отрисовывать собственную HTML-форму внутри диалога подтверждения — в Django Admin для этого пришлось бы создавать промежуточную страницу. Для операций над отдельными строками используйте @row_action и @link_row_action; аналогов в Django Admin у них нет.
Разрешения и аутентификация
Django Admin делегирует эти задачи модулю django.contrib.auth. starlette-admin разделяет проблему на две части: AuthProvider отвечает на вопрос «кто этот пользователь», а методы представлений — на вопрос «что он может делать».
| Django Admin | starlette-admin |
|---|---|
вход через django.contrib.auth |
AuthProvider (встроенная страница входа) или OAuthProvider (redirect-процесс OIDC) |
request.user |
request.state.admin_user |
has_module_permission |
is_accessible(request) у представления |
has_view_permission |
can_view_detail(request) |
has_add_permission |
can_create(request) |
has_change_permission |
can_edit(request) |
has_delete_permission |
can_delete(request) |
get_readonly_fields для каждого пользователя |
can_access_field(request, field) |
| Аналог отсутствует | can_export(request), can_import(request), is_action_allowed(request, name) |
Следующее представление разрешает удаление только пользователям с ролью admin:
class ArticleView(ModelView):
def can_delete(self, request: Request) -> bool:
return "admin" in request.state.admin_user.roles
Каждый метод can_* получает запрос, поэтому ваши решения об авторизации могут опираться на текущего пользователя, HTTP-заголовки или любые другие данные запроса.
Hook'и сохранения и сигналы
| Django Admin | starlette-admin | Примечания |
|---|---|---|
save_model(request, obj, form, change) |
before_create / before_edit у представления |
Изначально асинхронные; получают разобранные данные формы вместе с экземпляром модели. |
delete_model |
before_delete |
Обрабатывает логику, предшествующую удалению. |
post_save и другие сигналы |
События | Например, admin.events.on(AdminEvent.AFTER_CREATE, handler) рассылает уведомление всем представлениям. |
История изменений LogEntry |
Реализуется через систему событий | Подпишитесь на AFTER_CREATE, AFTER_EDIT и AFTER_DELETE, чтобы заполнять собственную таблицу аудита. |
messages.success(request, ...) |
flash(request, ...) |
См. Flash Messages. |
Конфигурация уровня всего сайта
| Django Admin | starlette-admin |
|---|---|
admin.site.site_header, site_title |
Admin(title="...") |
| Собственный логотип через переопределение шаблона | Admin(logo_url="...", login_logo_url="...", favicon_url="...") |
AdminSite.index_template |
Admin(index_view=...) с widget'ами для полноценной dashboard-страницы |
Переопределения шаблонов в templates/admin/ |
Admin(templates_dir="..."), см. Templates |
Несколько экземпляров AdminSite |
Несколько экземпляров Admin, подключённых по разным путям приложения |
ModelAdmin.get_queryset |
get_list_query, get_count_query или get_detail_query для backend'а SQLAlchemy |
USE_I18N, LANGUAGES |
Admin(i18n_config=I18nConfig(default_locale="fr")) |
TIME_ZONE |
Admin(timezone_config=TimezoneConfig(...)), см. i18n and Timezones |
Что вы получаете при переходе
- Сквозная асинхронность: Обработчики, lifecycle hook'и и callback'и widget'ов могут быть корутинами, выполняющимися в вашем существующем event loop рядом с endpoint'ами FastAPI.
- Гибкость в выборе БД: Одна и та же конфигурация админ-панели работает независимо от того, используете ли вы SQLAlchemy, SQLModel, MongoDB через MongoEngine или Beanie либо Tortoise ORM.
- Встроенный экспорт и импорт: CSV, JSON и PDF, плюс Excel и другие форматы через
tablib. Экспортируйте записи напрямую или импортируйте данные пакетно с помощью wizard'а, который сначала показывает предпросмотр, обеспечивает валидацию на уровне строк и поддерживает опциональный upsert по первичному ключу. См. Export and Import. - Widget'ы для дашборда: Карточки статистики, ApexCharts и сетки макетов компонуются в index-страницы и custom view, поэтому для создания дашборда не нужен внешний пакет с темой. См. Custom Views and Widgets.
- Современный пользовательский интерфейс: Tabler (Bootstrap 5) даёт тёмную тему, переключатели видимости столбцов и подсветку результатов поиска по умолчанию.
Что нужно реализовать самостоятельно
- Аутентификация: Встроенной модели пользователя или базы разрешений нет. Реализуйте
AuthProvider.authenticate(), опираясь на хранилище данных, которое уже используется вашим приложением. - Журналирование аудита: starlette-admin не генерирует таблицу
LogEntry. Подключите систему событий к собственной таблице аудита. - Конфигурация UI на уровне модели: Удобства Django вроде модельных
choices,verbose_nameи валидаторов автоматически не переносятся. Задайте их на уровне поля starlette-admin с помощьюEnumField,label=иvalidators=.