You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI中实现DataTable服务端分页与过滤的最优方案及库推荐

FastAPI + DataTable 服务端分页与过滤实现方案

核心思路

DataTable的服务端模式要求后端接收分页、过滤、排序参数,执行数据库查询后返回指定格式的JSON数据。结合FastAPI的高性能和Django前端(模板渲染)的场景,核心是解析DataTable标准请求参数、高效执行数据库分页过滤,并返回符合DataTable要求的响应结构。

推荐库

  1. SQLAlchemy:作为ORM处理数据库查询,天然支持参数化过滤、排序和分页,避免SQL注入,适配绝大多数关系型数据库。
  2. fastapi-pagination:专为FastAPI设计的分页工具,简化分页逻辑,支持自定义请求参数适配DataTable格式。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:47:16