当前位置: 首页 > article >正文

Sqladmin - FastAPI框架下一键生成管理后台

介绍

Github 开源地址:

https://github.com/aminalaee/sqladmin

网站说明链接地址:

https://aminalaee.dev/sqladmin/

一个现代、优雅的 SQLAlchemy 管理后台工具,非常适合用在 FastAPI 项目中

SQLAdmin 是一个基于 FastAPI + SQLAlchemy 构建的管理后台框架,灵感来自于 Django Admin,目标是为 Python 项目提供:

• 🚀 简洁易用的后台界面

• 📋 基于 SQLAlchemy 的模型自动管理

• ⚙️ 快速 CRUD(增删改查)

• ✨ Jinja2 渲染漂亮的 Bootstrap 风格后台

功能描述
🎨 UI基于 Tabler(Bootstrap 风格)构建
🔁 CRUD 自动化自动根据模型生成增删改查
🔍 搜索 / 过滤表字段搜索、过滤支持
🧩 多数据库支持支持 SQLite、PostgreSQL、MySQL 等
🔐 自定义认证可扩展自定义登录(如你用的 AdminAuth)
🧠 异步支持与 FastAPI 完美配合,支持异步视图
🔧 高度可配置支持列隐藏、格式化、标签等配置项

支持models 的类型:

✅ 支持 SQLAlchemy 吗?是,必须基于 SQLAlchemy ORM 模型
✅ 支持 SQLAlchemy 1.x 吗?
✅ 支持 SQLAlchemy 2.x 吗?是,从 sqladmin 0.15.0+ 开始全面支持
❌ 支持 Tortoise ORM 吗?不支持
❌ 支持 Django ORM 吗?不支持

为什么使用?

很多项目都是异步,而异步里面ORM 性能最好的就是 SQLAlchemy 2.0

特性优势是否推荐
✅ 新的 2.0 风格语法更清晰、类型安全,统一 async / sync 用法强烈推荐
✅ 原生异步支持(async_engine)适配 FastAPI、aiohttp 等异步框架
✅ Declarative Mapping 更加清晰不再混用 Base = declarative_base() 和 mapper()
✅ 更强的类型提示支持IDE 友好,调试更舒服
✅ Session 语义改进显式事务控制、更加安全
✅ 官方长期维护方向所有新功能只在 2.x 上更新
特性 / 框架SQLAlchemy 2.0 (async)Tortoise ORMasyncpg (原生驱动)
⭐ 异步支持✅ 原生 async API(2.0 起)✅ 原生 async✅ 原生 async
🎯 ORM 支持✅ 完整 ORM(经典 + 声明式)✅ 类 Django 的 ORM❌ 没有 ORM,需手写 SQL
⚙️ 事务处理✅ async with session.begin()✅ transaction() 上下文✅ 需手动写 SQL + 事务处理
🔧 灵活性✅ 高(支持 ORM + Core)中等(ORM风格较固定)极高(最贴近 SQL)
📚 学习曲线稍高(但文档全)较低,适合 Django 用户中等(需掌握 SQL)
🚀 性能优(合理用 async)优(轻量)最优(直接操作 protocol)
✅ 类型支持✅ Pydantic 配合良好✅ 也能配合 Pydantic 使用❌ 无自动转换,手动处理
🧩 支持的数据库多(PostgreSQL, MySQL, SQLite等)PostgreSQL、MySQL、SQLitePostgreSQL 专用
🔍 社区 & 文档非常成熟(官方长期维护)活跃,偏小众官方是 PostgreSQL 的推荐驱动
你的需求推荐方案
需要强大的 ORM + 类型检查 + 可扩展性SQLAlchemy 2.0 + Async
想快速上手、有 Django ORM 背景Tortoise ORM
要极致性能,手写 SQL 不怕麻烦asyncpg

结合应用

from sqlalchemy import Column, Integer, String, create_engine,Enum as SAEnum,JSON
from sqladmin.authentication import AuthenticationBackend
import json
import hashlib
from sqlalchemy import event

from sqlalchemy.orm import declarative_base
from enum import Enum
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()
engine = create_engine(
    "sqlite:///example.db",
    connect_args={"check_same_thread": False},
)

# 定义枚举类型
class GenderEnum(str, Enum):
    MALE = "male"
    FEMALE = "female"
    OTHER = "other"

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    name = Column(String)
    gender = Column(SAEnum(GenderEnum), nullable=False, comment="性别")
    password = Column("password", String, nullable=False)  # 真实存储加密后的密码

class JsonConfig(Base):
    __tablename__ = "json_config"

    id = Column(Integer, primary_key=True)
    name = Column(String)
    config = Column(JSON)

Base.metadata.create_all(engine)  # Create tables,后面改了字段需要删除

from fastapi import FastAPI
from sqladmin import Admin, ModelView
from fastapi import Request

app = FastAPI()

class AdminAuth(AuthenticationBackend):
    async def login(self, request: Request) -> bool:
        form = await request.form()
        username, password = form["username"], form["password"]

        # Validate username/password credentials
        # And update session
        if username == "admin" and password == "123456":
            request.session.update({"sqladmin_token": "..."})
            return True
        else:
            return False
        return True

    async def logout(self, request: Request) -> bool:
        # Usually you'd want to just clear the session
        request.session.clear()
        return True

    async def authenticate(self, request: Request) -> bool:
        token = request.session.get("sqladmin_token")

        if not token:
            return False

        # Check the token in depth
        return True

authentication_backend = AdminAuth(secret_key="secret_key")

admin = Admin(app, engine,base_url="/super",authentication_backend=authentication_backend)

class UserAdmin(ModelView, model=User):
    self_md5_salt = "123456"
    column_list = [User.id, User.name,User.gender,User.password]

    # 自定义列标签(让 SQLAdmin UI 显示中文)
    column_labels = {
        "id": "用户 ID",
        "name": "姓名",
        "gender": "性别",
        "password": "密码",
    }
    async def insert_model(self, request: Request, data: dict):
        """拦截插入逻辑,确保 `password` 经过 MD5 加密"""
        raw_password = data.pop("password", None)
        if raw_password:
            data["password"] = hashlib.md5((raw_password+self.self_md5_salt).encode()).hexdigest()
        return await super().insert_model(request, data)

    async def update_model(self, request: Request, pk: str, data: dict):
        """拦截更新逻辑,确保 `password` 经过 MD5 加密"""
        raw_password = data.pop("password", None)
        if raw_password:
            data["password"] = hashlib.md5((raw_password+self.self_md5_salt).encode()).hexdigest()
        return await super().update_model(request, pk, data)

class JsonConfigAdmin(ModelView, model=JsonConfig): 
    column_list = [JsonConfig.id, JsonConfig.name,JsonConfig.config]
    # 前端页面插入的时候 只能使用双引号的json 不能使用单引号的json

admin.add_view(UserAdmin)
admin.add_view(JsonConfigAdmin)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)
# uvicorn test_sqladmin:app --host 127.0.0.1 --port 8000 --reload
# 后台地址: http://127.0.0.1:8000/super

# pip install itsdangerous  sqladmin 

http://www.kler.cn/a/600416.html

相关文章:

  • python常见反爬思路详解
  • 网络基础梳理
  • OWASP Top漏洞说明
  • Python爬虫获取1688商品(按图搜索)接口的返回数据说明
  • vulnhub-Tr0ll ssh爆破、wireshark流量分析,exp、寻找flag。思维导图带你清晰拿到所以flag
  • 蓝桥杯——————数位排序(java)
  • uniapp自身bug | uniapp+vue3打包后 index.html无法直接运行
  • Android Compose 框架基本状态管理(mutableStateOf、State 接口)深入剖析(十四)
  • Unity将运行时Mesh导出为fbx
  • 基于websocketpp实现的五子棋项目
  • MIPI 详解:XAPP894 D-PHY Solutions
  • 北京交通大学第三届C语言积分赛
  • 新手如何使用 Milvus
  • 大数据学习(83)-数仓建模理论
  • 新版 eslintrc 文件弃用 .eslintignore已弃用 替代方案
  • x-cmd install | Wuzz - Web 开发与安全测试利器,交互式 HTTP 工具
  • 基于javaweb的SpringBoot公司财务管理设计与实现(源码+文档+部署讲解)
  • Linux上位机开发实战(编写API库)
  • VitePress由 Vite 和 Vue 驱动的静态站点生成器
  • Python:单例模式魔法方法