1. 簡介
本文詳細介紹了一個基于 FastAPI 框架的通用分頁處理模塊的實現。該模塊提供了標準的分頁參數處理、數據切片和響應格式化功能,可以輕松地集成到任何 FastAPI 項目中。
2. 代碼實現
2.1 導入必要的模塊
首先,我們需要導入所需的模塊:
from typing import Optional, List, Dict, Any
from fastapi import FastAPI, Query, HTTPException
from pydantic import BaseModel
from math import ceil
這些導入包括:
typing
: 提供類型提示支持fastapi
: FastAPI 框架的核心組件pydantic
: 用于數據驗證的模型類math.ceil
: 用于向上取整計算總頁數
2.2 分頁參數模型
定義分頁請求參數的數據模型:
class PaginationParams(BaseModel):"""分頁參數模型Attributes:page: 當前頁碼,從1開始page_size: 每頁數據條數total: 數據總條數"""page: int = Query(1, ge=1, description="當前頁碼,從1開始")page_size: int = Query(10, ge=1, le=100, description="每頁數據條數,1-100之間")total: Optional[int] = None
這個模型定義了:
page
: 當前頁碼,默認為1,必須大于等于1page_size
: 每頁數據條數,默認為10,范圍在1-100之間total
: 可選的總數據條數
2.3 分頁響應模型
定義標準的分頁響應格式:
class PaginatedResponse(BaseModel):"""分頁響應模型Attributes:items: 分頁數據列表total: 數據總條數page: 當前頁碼page_size: 每頁數據條數total_pages: 總頁數has_next: 是否有下一頁has_prev: 是否有上一頁"""items: List[Dict[str, Any]]total: intpage: intpage_size: inttotal_pages: inthas_next: boolhas_prev: bool
響應模型包含:
items
: 當前頁的數據列表total
: 數據總條數page
: 當前頁碼page_size
: 每頁條數total_pages
: 總頁數has_next
: 是否有下一頁has_prev
: 是否有上一頁
2.4 分頁核心函數
實現分頁處理的核心邏輯:
def paginate(items: List[Any],pagination: PaginationParams
) -> PaginatedResponse:"""通用分頁函數Args:items: 需要分頁的數據列表pagination: 分頁參數對象Returns:PaginatedResponse: 分頁后的數據響應對象Raises:HTTPException: 當頁碼超出范圍時拋出異常"""# 計算總條數total = len(items)# 計算總頁數total_pages = ceil(total / pagination.page_size)# 驗證頁碼是否有效if pagination.page > total_pages and total > 0:raise HTTPException(status_code=404, detail="Page not found")# 計算當前頁的數據切片start = (pagination.page - 1) * pagination.page_sizeend = start + pagination.page_size# 獲取當前頁數據current_items = items[start:end]# 構建分頁響應return PaginatedResponse(items=current_items,total=total,page=pagination.page,page_size=pagination.page_size,total_pages=total_pages,has_next=pagination.page < total_pages,has_prev=pagination.page > 1)
核心函數實現了:
- 計算數據總條數
- 計算總頁數
- 驗證頁碼有效性
- 計算數據切片范圍
- 獲取當前頁數據
- 構建標準響應
3. 使用示例
3.1 基本用法
from fastapi import FastAPI, Dependsapp = FastAPI()# 示例數據
items = [{"id": i, "name": f"Item {i}"} for i in range(100)]@app.get("/items/", response_model=PaginatedResponse)
async def get_items(pagination: PaginationParams = Depends()):return paginate(items, pagination)
3.2 API 調用示例
# 獲取第一頁,每頁10條數據
GET /items/?page=1&page_size=10# 獲取第二頁,每頁20條數據
GET /items/?page=2&page_size=20
3.3 響應示例
{"items": [{"id": 0, "name": "Item 0"},{"id": 1, "name": "Item 1"},// ... 更多數據],"total": 100,"page": 1,"page_size": 10,"total_pages": 10,"has_next": true,"has_prev": false
}
4. 特點和優勢
-
類型安全
- 使用 Python 類型注解
- 使用 Pydantic 模型進行數據驗證
- IDE 友好,提供代碼補全支持
-
參數驗證
- 自動驗證頁碼和每頁條數
- 防止無效的分頁參數
- 提供清晰的錯誤信息
-
標準響應
- 統一的響應格式
- 包含分頁元數據
- 便于前端處理
-
異常處理
- 優雅處理無效頁碼
- 返回標準的 HTTP 錯誤碼
- 提供清晰的錯誤信息
5. 注意事項
-
頁碼計數
- 頁碼從 1 開始計數
- 無效頁碼會返回 404 錯誤
-
數據限制
- 每頁條數限制在 1-100 之間
- 可以根據需要調整限制范圍
-
性能考慮
- 適用于內存中的數據列表
- 對于數據庫查詢,建議使用數據庫級別的分頁
6. 總結
這個分頁模塊提供了一個完整的解決方案,可以輕松處理 FastAPI 應用中的分頁需求。它的設計注重:
- 代碼的可讀性和可維護性
- 類型安全和參數驗證
- 標準化的響應格式
- 良好的錯誤處理
通過使用這個模塊,可以大大簡化 API 開發中的分頁實現,提高開發效率和代碼質量。