FastAPI可扩展查询类复用问题:子类无法继承父类字段
解决FastAPI中查询参数基类字段无法被子类继承的问题
问题根源
你遇到的问题是因为FastAPI中直接继承带有Query注解的类时,父类的查询参数不会自动被子类继承。这是因为Query是用于标记单个参数的依赖项,而非普通的类属性继承逻辑;如果是用普通类而非Pydantic模型定义参数,FastAPI无法识别父类的Query字段并将其纳入子类的参数解析流程。
解决方案
下面提供两种可靠的实现方式,实现查询参数的复用:
方案1:基于Pydantic BaseModel继承(推荐)
利用Pydantic模型的字段继承特性,将公共参数定义在基类模型中,子类直接继承即可自动获取父类字段,同时保留Query的验证和描述能力。
from fastapi import FastAPI, Query, Depends from pydantic import BaseModel app = FastAPI() # 公共查询参数基类 class BaseParams(BaseModel): name: str | None = Query(None, description="姓名") age: int | None = Query(None, ge=0, le=120, description="年龄") # 教师专属参数子类 class TeacherParams(BaseParams): subject: str | None = Query(None, description="教授科目") # 学生专属参数子类 class StudentParams(BaseParams): grade: str | None = Query(None, description="所在年级") # 教师查询接口 @app.get("/teachers") async def list_teachers(params: TeacherParams = Depends()): return params.dict() # 学生查询接口 @app.get("/students") async def list_students(params: StudentParams = Depends()): return params.dict()
这种方式的优势是代码简洁,同时保留Pydantic的字段验证和FastAPI的自动文档生成能力,子类会自动包含父类的所有查询参数。
方案2:基于依赖函数组合
如果不想使用Pydantic模型,可以通过依赖函数的嵌套调用,实现公共参数的复用:
from fastapi import FastAPI, Query, Depends app = FastAPI() # 公共参数依赖函数 async def get_base_params( name: str | None = Query(None, description="姓名"), age: int | None = Query(None, ge=0, le=120, description="年龄") ): return {"name": name, "age": age} # 教师参数依赖函数,组合公共参数 async def get_teacher_params( subject: str | None = Query(None, description="教授科目"), base_params: dict = Depends(get_base_params) ): return {**base_params, "subject": subject} # 学生参数依赖函数,组合公共参数 async def get_student_params( grade: str | None = Query(None, description="所在年级"), base_params: dict = Depends(get_base_params) ): return {**base_params, "grade": grade} # 教师查询接口 @app.get("/teachers") async def list_teachers(params: dict = Depends(get_teacher_params)): return params # 学生查询接口 @app.get("/students") async def list_students(params: dict = Depends(get_student_params)): return params
这种方式适合不需要Pydantic模型验证的场景,通过字典合并将公共参数和子类参数组合在一起。
内容的提问来源于stack exchange,提问作者Carlos Rojas
相关产品推荐
相关产品推荐

