fastapi admin,即开即用的后台框架
在上一节FastAPI系列19:fastapi admin,即开即用的后台框架(1),我们讲解了fastapi-amis-admin的基本使用,本节我们深入学习fastapi-amis-admin。在fastapi-amis-admin中 AdminSite代表着整个后台应用,它可以包含多个AdminApp,而每一个AdminApp中可以有多个AdminGroup作为页面导航分组,每个AdminGroup可以包含多个PageSchemaAdmin管理页面,这样就构成了整个后台应用基本结构。
核心概念
1、AdminSite, 后台系统的核心管理类
AdminSite继承自BaseAdminSite,负责整个后台的初始化、路由挂载、配置管理和资源注册。
初始化后台站点配置
接受 Settings、FastAPI 实例和可选数据库 engine 参数。
Settings 用来配置后台是否启动调试、挂载路径、数据库连接地址、CDN 路径、AMIS 版本等 。
在初始化时会配置 FastAPI 应用对象,包括路由路径、文档地址、依赖注入等。
管理数据库引擎
内部维护默认 SQLAlchemy 同步/异步数据库引擎(由 Settings.database_url_async 或 engine 参数提供)。
后续注册的 ModelAdmin 和 AdminApp 默认使用该数据库连接 。
注册与挂载后台功能
支持通过 @site.register_admin 装饰器注册 ModelAdmin, PageAdmin, FormAdmin 等多种后台资源。
mount_app(app) 方法将后台整套界面挂载至主 FastAPI,默认路径为 /admin/,同时支持 OpenAPI 和 Redoc 文档的副本接口 。
支持自定义子类扩展
用户可继承 AdminSite 重写模板(template_name)、菜单结构、自定义静态资源、权限校验逻辑等 。
示例:覆盖 get_page() 方法修改站点名称和 logo,或卸载默认 DocsAdmin/ReDocsAdmin 。
权限与认证集成
内置权限判断 has_page_permission,可通过集成 fastapi-user-auth 等组件实现用户登录、RBAC 权限控制 。
支持全局依赖注入和路由权限验证的穿透机制。
2、AdminApp,用于模块化组织后台功能
AdminApp 是 FastAPI‑Amis‑Admin 中的一个重要管理单元,位于 AdminSite 与具体管理类(如 ModelAdmin、PageAdmin)之间,用于模块化组织后台功能。
隶属关系
AdminSite 是顶层后台应用,它可以注册多个 AdminApp。
每个 AdminApp 又可以注册多个后台管理类(如模型、页面、表单等) 。
功能组织
支持将相关功能模块化管理,如:BlogApp 集中管理博客相关 CRUD;UserApp 管理用户功能。
可以注册 ModelAdmin、PageAdmin、FormAdmin 等多个管理资源。
自定义配置
支持独立 router_prefix(URL 前缀)与 AMIS 风格页面配置。
可选配置独立数据库连接(通过 engine 参数进行异步或同步 DB 操作) 。
层级嵌套
AdminApp 本身也是可注册的管理类,因此可以作为“子后台”,嵌套在另一个 AdminApp 或 AdminSite 中使用:比如 AdminSite → AdminAPP1 → AdminAPP11、AdminAPP12 等
3、AdminGroup,用于组织页面导航分组
AdminGroup是 fastapi-amis-admin 中用来组织页面导航分组的组件,专门用来聚合多个页面项(如 PageAdmin、LinkAdmin、IframeAdmin 等),统一展示在后台侧边栏菜单中的一个折叠分组里。
页面分组导航
允许多个子页面以逻辑分类方式展示,如“文档管理”分组下可以放 Docs、ReDocs、API 文档等页面。
提高后台界面的可读性和可维护性。
权限自动过滤
调用 get_page_schema_children(request) 获取子页面,在渲染前会根据当前用户权限自动过滤(无权限则不显示)。
子页面嵌套在组中,但权限仍独立控制。
可组合与可迭代
实现迭代接口,可在 AdminApp 或 AdminSite 注册时统一遍历生成路由等处理。
支持动态注册子页面。
4、PageSchemaAdmin及其子类PageAdmin、LinkAdmin、IframeAdmin、TemplateAdmin
PageSchemaAdmin 是 fastapi‑amis‑admin 中用于管理后台导航页面的核心基类,提供页面显示和权限控制的基本能力,它包含 PageAdmin、LinkAdmin、IframeAdmin、TemplateAdmin 等具体页面管理子类。它是页面导航项的标准接口和权限网关,定义如何展示在后台导航中、何时可访问,并生成 AMIS 所需的页面 Schema。
具体页面管理子类
静态页面:通过设置 PageAdmin.page 提供 AMIS JSON 或通过 get_page() 方法动态获取页面内容;
外链页面:使用 LinkAdmin 定义跳转链接;
嵌入页面:使用 IframeAdmin 嵌入第三方连接;
模板页面:使用 TemplateAdmin 渲染 Jinja2 模板。
5、BaseActionAdmin及其子类ModelAdmin、FormAdmin
BaseActionAdmin 是 fastapi-amis-admin 框架中用于实现页面操作行为(如按钮、表单提交)的基类,基于 AMIS 中的 Action 概念,BaseActionAdmin 允许你在页面上定义附加行为(例如按钮触发的弹窗、确认对话框、执行操作等)。
ModelAdmin、FormAdmin 等继承自 BaseActionAdmin,因此具备“行为”注册能力,如创建、更新、删除、批量操作按钮。
6、PageSchemaAdmin 及BaseActionAdmin的结构关系
基础教程
1、页面管理
普通页面
我们在前一节的“Hello World”示例的基础上,再实现一个获取当前时间的页面。
在main.py中的site.mount_app(app)
上方添加:
import time
from fastapi import Request
@site.register_admin
class CurrentTimePageAdmin(admin.PageAdmin):
page_schema = 'Current Time Page'
page = Page.model_validate(
{
"type": "page",
"title": "Current Time Page",
"body": {
"type": "markdown",
"value": "**当前时间:** " + time.strftime('%Y-%m-%d %H:%M:%S')
}
}
)
链接页面
LinkAdmin
实现在菜单列表显示一个链接跳转菜单,点击菜单后将通过打开一个新的浏览器标签,访问设置的链接:
from fastapi_amis_admin.admin import admin
from fastapi_amis_admin.amis import PageSchema
@site.register_admin
class GitHubLinkAdmin(admin.LinkAdmin):
# 通过page_schema类属性设置页面菜单信息;
page_schema = PageSchema(label='AmisLinkAdmin', icon='fa fa-github')
# 设置跳转链接
link = 'https://example.com'
iframe页面
IframeAdmin
实现在菜单列表显示一个菜单,点击菜单后将通过在当前页面内嵌一个框架。使用方法与LinkAdmin
非常相似,不同的仅仅是链接的打开方式,
@site.register_admin
class ReDocsAdmin(admin.IframeAdmin):
# 设置页面菜单信息
page_schema = PageSchema(label='Redocs', icon='fa fa-book')
# 设置跳转链接
@property
def src(self):
return self.app.site.settings.site_url + '/redoc'
2、表单管理
FormAdmin
实现在菜单列表显示一个菜单,点击菜单后将展现一个amis
表单页面。
from fastapi_amis_admin.admin import admin
from fastapi_amis_admin.crud import BaseApiOut
from fastapi_amis_admin.models.fields import Field
from pydantic import BaseModel
from starlette.requests import Request
from fastapi_amis_admin.amis import Form
from typing import Any
@site.register_admin
class UserLoginFormAdmin(admin.FormAdmin):
page_schema = 'UserLoginForm'
# 配置表单信息, 可省略
form = Form(title='这是一个测试登录表单', submitText='登录')
# 创建表单数据模型
class schema(BaseModel):
username: str = Field(..., title='用户名', min_length=3, max_length=30)
password: str = Field(..., title='密码')
# 处理表单提交数据
async def handle(self, request: Request, data: BaseModel, **kwargs) -> BaseApiOut[Any]:
if data.username == 'amisadmin' and data.password == 'amisadmin':
return BaseApiOut(msg='登录成功!', data={'token': 'xxxxxx'})
return BaseApiOut(status=-1, msg='用户名或密码错误!')
3、模板管理
在某些情况下,amis
页面可能并不方便实现你的复杂界面展示,或者你更加倾向于使用模板渲染方式展示管理页面,这时你可以使用TemplateAdmin
实现你的需求。
在根目录下创建模板目录templates
,并在模板目录创建simple.html
文件,内容如下:
from fastapi_amis_admin.admin.admin import Jinja2Templates
import datetime
from typing import Dict
@site.register_admin
class SimpleTemplateAdmin(admin.TemplateAdmin):
page_schema = PageSchema(label='SimpleTemplate', icon='fa fa-link')
templates: Jinja2Templates = Jinja2Templates(directory='templates')
template_name = 'simple.html'
async def get_page(self, request: Request) -> Dict[str, Any]:
return {'current_time': datetime.datetime.now()}
以下是模版文件代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Current Time</title>
</head>
<body>
<h1>Current Time</h1>
<p>The current time is: {{ current_time }}</p>
</body>
</html>
4、模型管理
模型管理在后台管理中是最为常用的一个管理类,fastapi-amis-admin目前已经实现针对数据模型常用的各种基本操作,并且你仍然可以在此基础上做出更多个性化的拓展。
SQLAlchemy Schema
from sqlalchemy import String, Integer, Boolean, ForeignKey, Select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from typing import Optional
class Base(DeclarativeBase):
pass
class CategorySchema(BaseModel):
id: Optional[int] = Field(default=None, primary_key=True, nullable=False)
name: str = Field(title="CategoryName")
description: str = Field(default="", title="CategoryDescription")
class Config:
# orm_mode = True
from_attributes = True
# 创建SQLAlchemy 2.0模型,详细请参考: https://docs.sqlalchemy.org/en/20/orm/quickstart.html
class Category(Base):
__tablename__ = "category"
__pydantic_model__ = CategorySchema # 指定模型对应的Schema类.省略可自动生成,但是建议指定.
id: Mapped[int] = mapped_column(primary_key=True, nullable=False)
name: Mapped[str] = mapped_column(String(100), unique=True, index=True, nullable=False)
description: Mapped[str] = mapped_column(String(255), default="")
Admin Page
# 注册ModelAdmin
@site.register_admin
class CategoryAdmin(admin.ModelAdmin):
page_schema = '分类管理'
# 配置管理模型
model = Category