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

FastAPI同时传UploadFile与JSON报422 Unprocessable Entity如何修复

问题原因

这个报错是FastAPI的请求解析规则和参数声明、请求格式不匹配导致的,核心逻辑如下:

  • 只要接口中声明了UploadFile/File类型的参数,FastAPI就会要求请求必须使用multipart/form-data编码,不再支持直接解析application/json格式的原始请求体。
  • 你当前直接把CreatePlace结构的JSON作为整个请求体发送,在multipart/form-data规则下,FastAPI会默认去读名为place的表单字段,把这个字段的内容解析为CreatePlace模型,你没传这个字段,自然会报所有字段缺失的422错误。
  • 移除UploadFile参数后,FastAPI会自动切回JSON请求体解析模式,直接把请求体映射到CreatePlace模型,所以不会报错。
修复方案

选改动最小的方案即可,不需要调整原有Pydantic模型定义:

  1. 首先补充导入需要的依赖:
from fastapi import Form
import json
import os # 用于处理文件路径,避免路径遍历漏洞
  1. 修改接口参数声明,将place参数改为从表单字段读取字符串,再手动解析为Pydantic模型,同时优化下文件保存的安全逻辑:
@app.post('/create_place')
def create_place(
    place: str = Form(...),
    file: UploadFile = File(...),
    db: Session = Depends(get_db)
):
    # 解析表单中传入的place JSON字符串
    try:
        place_obj = schemas.CreatePlace(**json.loads(place))
    except:
        raise HTTPException(status_code=400, detail="place字段需传入合法JSON字符串")
    
    if auth.check_auth_user(place_obj.token):
        user_email = auth.decode_token(place_obj.token)
        user = crud.get_user_by_email(db=db, email=user_email['sub'])
        if user.is_admin:
            place_db = crud.get_places_by_name(db, name=place_obj.name)
            if place_db:
                raise HTTPException(status_code=400, detail="Place already added")
            # 过滤文件名中的路径字符,防止路径遍历攻击
            safe_name = os.path.basename(file.filename)
            save_path = f"media/{safe_name}"
            with open(save_path, "wb") as image:
                shutil.copyfileobj(file.file, image)
            return crud.create_places(db=db, place=place_obj, img=save_path)
        else:
            raise HTTPException(status_code=400, detail="You are not admin")
    else:
        raise HTTPException(status_code=400, detail="You are not auth")
  1. 调整前端请求格式:
    不要直接发送JSON请求体,改为构造multipart/form-data格式请求,包含两个字段:
    • file:你要上传的文件
    • place:值为原来的JSON内容序列化后的字符串,比如你之前测试用的JSON就直接转成字符串作为这个字段的值即可。

不推荐把文件转base64塞到JSON里传的方案,大文件场景下会额外增加30%左右的传输体积,解析性能也更差。

内容的提问来源于stack exchange,提问作者ZARAJENIY na 100

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:01:29