跳转至
受监督的机器翻译

本文内容由机器翻译生成,并遵循人工维护的术语表与风格指南。由于译文未经逐行人工审校,可能偶有错误或表达不当之处。

如有任何出入,请以英文原版为准,英文原版是权威来源。

阅读英文原版

文档全新上线  ·  了解更新内容

为 FastAPI & Starlette 打造
可扩展的管理界面

根据你的 SQLAlchemy、SQLModel、Beanie、MongoEngine 或 Tortoise ORM 模型生成完整的管理界面。starlette-admin 基于 Tabler UI 组件库构建,为你提供列表视图、自动生成的表单、数据导出以及安全的身份认证。整个界面都可以用 Python 配置,无需编写任何前端代码。

pip install starlette-admin
starlette-admin dashboard showing statistical widgets, recent activity tables, and a sidebar for model views

内置功能

你所需的一切开箱即用。每项核心功能都带有完善的扩展点文档,方便你按自己的需求进行定制。

一切皆 Python

使用纯 Python API 构建完整的管理界面,专为快速开发语法可读长期可维护而设计。

挂载管理后台

注册一个模型,并把管理后台挂载到任意 FastAPI 或 Starlette 应用上。然后运行 fastapi dev 并打开 /admin

查看文档

main.py
from fastapi import FastAPI
from sqlalchemy import create_engine
from starlette_admin.contrib.sqla import Admin, ModelView

from models import Base, Post

engine = create_engine("sqlite:///blog.db")
Base.metadata.create_all(engine)

app = FastAPI()

admin = Admin(engine, title="Blog Admin", secret_key="change-me")
admin.add_view(ModelView(Post, icon="fa fa-newspaper"))
admin.mount_to(app)

视图

使用简单的类属性即可设置搜索、排序、默认排列顺序和导出格式。并通过 form_layout 排列新建与编辑表单。

查看文档

views.py
from starlette_admin.contrib.sqla import ModelView


class PostView(ModelView):
    fields = ["id", "title", "author", "content", "published", "created_at"]
    searchable_fields = ["title", "content"]
    fields_default_sort = [("created_at", True)]
    exporters = ["csv", "xlsx", "json"]
    form_layout = [
        ("title", "author"),
        "content",
        ("published", "created_at"),
    ]


admin.add_view(PostView(Post, icon="fa fa-newspaper"))

字段

重写任何自动检测的字段,以控制校验、页面级可见性,以及 starlette-admin 读取和展示值的方式。

查看文档

views.py
from starlette_admin import DateTimeField, RequestAction, StringField, TextAreaField
from starlette_admin.contrib.sqla import ModelView


class PostView(ModelView):
    fields = [
        "id",
        StringField("title", required=True, help_text="Shown on the blog"),
        TextAreaField("content", exclude_from_list=True),
        StringField(
            "author_email",
            getter=lambda request, obj: obj.author.email,
            formatter={RequestAction.LIST: lambda request, value: value or "unset"},
        ),
        DateTimeField("created_at", read_only=True, exclude_from_create=True),
    ]

过滤器

使用符合业务规则的自定义过滤器扩展内置查询构建器。你可以把所需的操作直接应用到底层数据库模型上。

查看文档

filters.py
from datetime import datetime
from typing import Any

from starlette_admin.contrib.sqla import ModelView
from starlette_admin.filters.base import BaseFilter, FilterApplyContext, FilterDataType


class ActiveThisMonthFilter(BaseFilter):
    name = "this_month"
    label = "Created this month"
    data_type = FilterDataType.NONE  # No value input. The range comes from now().

    def apply(self, ctx: FilterApplyContext) -> Any:
        now = datetime.utcnow()
        start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        col = getattr(ctx.view.model, ctx.field_name)
        return col.between(start, now)

class ProductView(ModelView):
    fields = [
        DateTimeField(
            "created_at",
            filters=[ActiveThisMonthFilter, ...],
        ),
    ]

动作

只需一个装饰器即可附加业务操作。确认弹窗、自定义表单和 Flash 消息都已内置于框架之中。

查看文档

views.py
from starlette.requests import Request
from starlette_admin import ActionSelection, action, flash
from starlette_admin.contrib.sqla import ModelView


class ArticleView(ModelView):
    actions = ["publish", "delete"]

    @action(
        name="publish",
        text="Mark as published",
        confirmation="Publish the selected articles?",
        submit_btn_text="Yes, publish",
    )
    async def publish(self, request: Request, selection: ActionSelection) -> None:
        articles = await selection.rows()
        for article in articles:
            article.published = True
        flash(request, f"{len(articles)} articles published.", "success")

认证

围绕你自己的凭据校验逻辑实现三个标准方法。登录页、会话和重定向都由 starlette-admin 替你处理。

查看文档

auth.py
from starlette.requests import Request
from starlette_admin.auth import AdminUser, AuthProvider, LoginFailed


class MyAuthProvider(AuthProvider):
    async def login(self, username, password, remember_me, request: Request) -> None:
        if not await check_credentials(username, password):
            raise LoginFailed("Invalid username or password")
        request.session["username"] = username

    async def authenticate(self, request: Request) -> AdminUser | None:
        if username := request.session.get("username"):
            return AdminUser(username=username)
        return None

    async def logout(self, request: Request) -> None:
        request.session.clear()


admin = Admin(engine, auth_provider=MyAuthProvider(), secret_key=SECRET)

仪表盘

使用统计、图表和表格部件组合出管理首页,它们会在每次请求时查询实时数据。

查看文档

dashboard.py
from starlette_admin import CardRowWidget, ChartWidget, CustomView, StatWidget

dashboard = CardRowWidget(
    children=[
        StatWidget(title="Orders", value_callback=count_orders, countup=True),
        StatWidget(title="Revenue", value_callback=sum_revenue, color="success"),
        ChartWidget(title="Sales", chart_type="area", series_callback=sales_series),
    ]
)

admin = Admin(
    engine,
    title="Shop Admin",
    secret_key="change-me",
    index_view=CustomView(menu_label="Dashboard", icon="fa fa-home", widget=dashboard),
)

插件与扩展

每一层都可以替换。将功能打包为独立自足的插件,或挂接到专门的扩展点,让框架贴合你的业务领域。

即插即用插件

零样板代码的插件

安装插件包并将其传入你的 Admin 实例即可。字段、转换器、模板和静态资源会自动完成装配。

from starlette_admin_geospatial import GeospatialPlugin
from starlette_admin.contrib.sqla import Admin

admin = Admin(
    engine,
    plugins=[GeospatialPlugin(default_zoom=13)],
)
阅读插件指南
扩展点

挂接到任意组件

预定义的接口让你可以独立地替换或扩展每个关注点。子类化所需的基类并注册即可。从认证流程到导出格式,一切皆可定制。

浏览全部扩展点