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

FastAPI实现仅获取Form提交字段(含空值),区分未提交项

FastAPI表单处理:区分空值提交与未提交字段

需求回顾

需要在POST/PUT路由中处理x-www-form-urlencode表单,实现:

  • 仅保留客户端提交的字段
  • 提交的空字符串转为null(即Python中的None)
  • 未提交的字段不纳入结果
  • 保留OpenAPI文档中字段的可选标识

解决方案

通过结合原始表单数据获取和显式声明Form参数生成文档的方式实现需求,代码如下:

from fastapi import APIRouter, Request, Form, Depends
from pydantic import BaseModel

router = APIRouter()

class MyResponse(BaseModel):
    message: str | None = None

# 自定义依赖:处理原始表单数据,区分提交空值与未提交字段
async def process_submitted_form(request: Request):
    raw_form = await request.form()
    processed_data = {}
    for field, value in raw_form.items():
        # 将空字符串转为None(对应JSON输出的null)
        processed_data[field] = value if value != "" else None
    return processed_data

@router.put("/{item_id}")
async def create_an_instance(
    item_id: int,
    # 声明Form参数用于生成OpenAPI文档,标记字段为可选
    name: str | None = Form(None),
    description: str | None = Form(None),
    # 注入处理后的表单数据
    form_data: dict = Depends(process_submitted_form)
) -> MyResponse:
    # 后续业务逻辑直接使用form_data即可
    print(f"Item ID: {item_id}")
    print(f"Processed Form Data: {form_data}")
    
    return MyResponse(message="处理完成")

场景验证

对应需求中的测试场景,输出结果完全符合预期:

  1. 提交name="a"、description="b" → {"name":"a","description":"b"}
  2. 提交name="a"、description="" → {"name":"a","description":None}
  3. 仅提交name="a" → {"name":"a"}
  4. 提交name="" → {"name":None}
  5. 提交name=""、description="" → {"name":None,"description":None}

方案优势

  • 文档兼容:通过显式声明Form(None)参数,保留OpenAPI文档中字段的可选标识
  • 精准区分:直接读取原始表单数据,彻底解决"未提交字段"与"提交空值"的混淆问题
  • 格式兼容:完全支持x-www-form-urlencode提交格式,无需切换为JSON

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:35:33