FastAPI中实现DataTable服务端分页与过滤的最优方案及库推荐
FastAPI + DataTable 服务端分页与过滤实现方案
核心思路
DataTable的服务端模式要求后端接收分页、过滤、排序参数,执行数据库查询后返回指定格式的JSON数据。结合FastAPI的高性能和Django前端(模板渲染)的场景,核心是解析DataTable标准请求参数、高效执行数据库分页过滤,并返回符合DataTable要求的响应结构。
推荐库
- SQLAlchemy:作为ORM处理数据库查询,天然支持参数化过滤、排序和分页,避免SQL注入,适配绝大多数关系型数据库。
- fastapi-pagination:专为FastAPI设计的分页工具,简化分页逻辑,支持自定义请求参数适配DataTable格式。
- Pydantic:FastAPI自带的参数校验工具,用于解析DataTable的复杂嵌套请求参数(如搜索、排序参数)。
分步实现示例
1. 安装依赖
pip install fastapi uvicorn sqlalchemy fastapi-pagination
2. 定义数据库模型(SQLAlchemy)
# models.py from sqlalchemy import Column, Integer, String, Float from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Product(Base): __tablename__ = "products" id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True) price = Column(Float) category = Column(String, index=True)
3. 解析DataTable请求参数(Pydantic)
# schemas.py from pydantic import BaseModel, Field from typing import Optional class DataTableRequest(BaseModel): draw: int start: int length: int search_value: Optional[str] = Field(alias="search[value]") order_column: Optional[str] = Field(alias="order[0][column]") order_dir: Optional[str] = Field(alias="order[0][dir]")
4. 实现FastAPI接口
# main.py from fastapi import FastAPI, Depends from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import create_engine, asc, desc from sqlalchemy.orm import sessionmaker, Session from models import Base, Product from schemas import DataTableRequest # 数据库配置 SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # 创建数据库表 Base.metadata.create_all(bind=engine) app = FastAPI() # 配置CORS(适配Django前端跨域请求) app.add_middleware( CORSMiddleware, allow_origins=["http://your-django-domain.com"], # 生产环境指定具体域名 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 获取数据库会话 def get_db(): db = SessionLocal() try: yield db finally: db.close() # DataTable服务端接口 @app.post("/api/products/datatable") def get_products(request: DataTableRequest, db: Session = Depends(get_db)): # 构建基础查询 query = db.query(Product) # 全局模糊过滤 if request.search_value: search_term = f"%{request.search_value}%" query = query.filter( Product.name.like(search_term) | Product.category.like(search_term) ) # 排序处理 column_map = { "0": Product.id, "1": Product.name, "2": Product.price, "3": Product.category } if request.order_column and request.order_dir: sort_column = column_map.get(request.order_column) if sort_column: query = query.order_by(asc(sort_column) if request.order_dir == "asc" else desc(sort_column)) # 统计总数与分页 total_records = query.count() paginated_data = query.offset(request.start).limit(request.length).all() # 返回DataTable要求的格式 return { "draw": request.draw, "recordsTotal": total_records, "recordsFiltered": total_records, # 若有过滤逻辑,此处改为过滤后的记录数 "data": [ { "id": item.id, "name": item.name, "price": item.price, "category": item.category } for item in paginated_data ] }
5. Django前端DataTable配置
在Django模板中配置DataTable,开启服务端模式:
<!-- Django模板内代码 --> <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css"> <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script> <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script> <table id="products-table" class="display" style="width:100%"> <thead> <tr> <th>ID</th> <th>名称</th> <th>价格</th> <th>分类</th> </tr> </thead> </table> <script> $(document).ready(function() { $('#products-table').DataTable({ serverSide: true, ajax: { url: "http://your-fastapi-domain/api/products/datatable", type: "POST" }, columns: [ { data: "id" }, { data: "name" }, { data: "price" }, { data: "category" } ] }); }); </script>
注意事项
- 过滤逻辑扩展:如需单列精确过滤,可在
DataTableRequest中添加对应字段(如category_filter),并在查询中增加Product.category == request.category_filter条件。 - SQL注入防护:始终使用SQLAlchemy的ORM查询或参数化查询,禁止直接拼接SQL语句。
- 性能优化:为过滤、排序字段添加数据库索引,提升大表查询速度。
内容的提问来源于stack exchange,提问作者Jac
相关产品推荐
相关产品推荐

