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

FastAPI中使用Depends时隐藏Pydantic 2字段的问题排查

问题分析

你的代码没有错误,这种差异是FastAPI的预期行为,原因在于它对Body()和Depends()注入的处理逻辑不同:

  • 使用Body()时,FastAPI会直接使用你重写后的模型整体JSON Schema,所以hidden_field会被过滤掉,不会出现在文档中。
  • 使用Depends()时,FastAPI会将模型拆解为独立的字段(默认作为查询参数),逐个提取字段元数据生成文档,这个过程不会触发你重写的__get_pydantic_json_schema__方法,因此hidden_field仍会显示。

解决方法

方案1:公开/内部模型分离(最可靠的常规方案)

创建两个模型,一个面向终端用户(仅包含可见字段),一个面向开发者(包含所有字段),通过依赖函数完成转换:

from pydantic import BaseModel
from fastapi import Depends

# 面向终端用户的公开模型
class PublicItem(BaseModel):
    visible_field: str

# 面向开发者的内部模型
class Item(BaseModel):
    visible_field: str
    hidden_field: str

def get_item(public_item: PublicItem = Depends()) -> Item:
    # 这里可从配置、数据库或其他开发者专属渠道获取hidden_field的值
    return Item(visible_field=public_item.visible_field, hidden_field="dev_only_value")

@app.get("/test")
def test_get(item: Item = Depends(get_item)):
    return {"item": item}

这种方式下,接口文档只会显示visible_field,同时开发者能拿到完整的Item实例。

方案2:自定义OpenAPI Schema统一过滤字段

通过修改FastAPI生成的OpenAPI Schema,全局移除标记为hidden的字段,同时兼容Body()和Depends()场景:

from fastapi import FastAPI
from pydantic import BaseModel, Field
from fastapi.openapi.utils import get_openapi

app = FastAPI()

class Item(BaseModel):
    visible_field: str
    hidden_field: str = Field(json_schema_extra={"hidden": True})

def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    # 生成基础OpenAPI Schema
    openapi_schema = get_openapi(
        title="Custom API",
        version="1.0.0",
        description="API with hidden fields",
        routes=app.routes,
    )
    # 过滤所有标记为hidden的字段
    for path in openapi_schema["paths"].values():
        for operation in path.values():
            # 处理请求体中的字段
            if "requestBody" in operation:
                for media_type in operation["requestBody"]["content"].values():
                    schema = media_type["schema"]
                    if "properties" in schema:
                        schema["properties"] = {
                            k: v for k, v in schema["properties"].items()
                            if not v.get("hidden", False)
                        }
            # 处理查询参数中的字段
            if "parameters" in operation:
                operation["parameters"] = [
                    param for param in operation["parameters"]
                    if not param.get("schema", {}).get("hidden", False)
                ]
    app.openapi_schema = openapi_schema
    return openapi_schema

# 替换默认的openapi生成逻辑
app.openapi = custom_openapi

@app.get("/test")
def test_get(item: Item = Depends()):
    return {"item": item}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:20:19