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

FastAPI中如何自定义自关联模型的嵌套响应字段?

解决FastAPI分类接口返回字段冗余的方案

核心思路是通过Pydantic模型定义需要返回的字段,FastAPI会自动根据该模型序列化返回结果,过滤掉冗余字段。结合自关联模型的特性,具体步骤如下:

1. 定义Pydantic序列化模型

首先创建一个Pydantic模型,只包含你需要返回的字段,并处理自关联的子分类结构:

from pydantic import BaseModel, Optional
from typing import List, ForwardRef

# 处理自关联的循环引用
CategoryResponse = ForwardRef('CategoryResponse')

class CategoryResponse(BaseModel):
    name: str
    slug: str
    order: int
    icon: Optional[str] = None  # 适配模型中可能为null的字段
    language_code: str
    child: Optional[List[CategoryResponse]] = []  # 自关联子分类,需与Django模型的related_name一致

    class Config:
        orm_mode = True  # 允许直接从ORM模型转换为Pydantic模型
  • orm_mode=True是关键配置,让Pydantic能够识别并读取Django/SQLAlchemy ORM模型的属性。
  • 子分类字段child需要和你Django模型中related_name的值保持一致(如果模型里related_name是children,这里也要同步修改)。

2. 修改路由逻辑

在路由中指定response_model为上面定义的CategoryResponse,同时查询时预加载子分类字段避免性能问题:

场景1:使用SQLAlchemy连接数据库

假设你已经通过SQLAlchemy映射了Django的Category模型:

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session, selectinload
from database import get_db  # 你的数据库会话依赖
from models import Category  # SQLAlchemy映射的Category模型

router = APIRouter()

@router.get("/categories/", response_model=List[CategoryResponse])
def get_all_categories(db: Session = Depends(get_db)):
    # 查询根分类(parent为空),并预加载子分类避免N+1查询
    categories = db.query(Category)\
                   .filter(Category.parent.is_(None))\
                   .options(selectinload(Category.child))\
                   .all()
    return categories

场景2:直接使用Django ORM

如果你的FastAPI项目直接使用Django的ORM操作数据库:

from fastapi import APIRouter
from myapp.models import Category  # Django的Category模型

router = APIRouter()

@router.get("/categories/", response_model=List[CategoryResponse])
def get_all_categories():
    # 预加载子分类,提升查询性能
    categories = Category.objects.filter(parent__isnull=True).prefetch_related('child')
    return categories

关键说明

  • FastAPI会自动根据response_model过滤字段,只返回你在Pydantic模型中定义的内容。
  • 预加载子分类(selectinload/prefetch_related)是为了避免多次查询数据库的N+1性能问题,必须加上。
  • 如果需要返回多级嵌套的子分类,Pydantic会自动递归序列化,无需额外处理。

内容的提问来源于stack exchange,提问作者mirodil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:13:27