FastAPI接口无法识别请求体字段问题咨询
问题:FastAPI新增用户日历接口返回参数缺失错误
测试新增用户日历接口时,服务器返回错误:
1 validation error for Request body -> user_calendar field required (type=value_error.missing)
路由代码
# Add User Calendar @router.post("", response_model=schemas.UserCalendar) async def add_user_calendar( user_calendar: schemas.UserCalendarBase, current_user: schemas.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), parent_slot: schemas.ParentSlot = None ): return usercalendar.add_user_calendar(user_calendar, current_user, db, parent_slot)
辅助函数代码
# generate a user calendar def generate_user_calendar( account_id, calendar_name = "offline_test", calendar_id = "test_calendar_id", timezone = "Europe/London" ): return { "account_id": account_id, "calendar_name": calendar_name, "calendar_id": calendar_id, "timezone": timezone } # create a user calendar def create_user_calendar(user_calendar, headers): return requests.post(API_ENDPOINT + "/calendar", headers=headers, json=user_calendar)
Schema代码
class UserCalendarBase(BaseModel): account_id: int calendar_name: str calendar_id: Union[str, None] timezone: str class Config: orm_mode = True
临时修改generate_user_calendar函数,在返回字典外层添加"user_calendar"顶层键后,接口可正常工作:
# generate a user calendar def generate_user_calendar( account_id, calendar_name = "offline_test", calendar_id = "test_calendar_id", timezone = "Europe/London" ): return { "user_calendar" : { "account_id": account_id, "calendar_name": calendar_name, "calendar_id": calendar_id, "timezone": timezone } }
但其他类似接口(如用户账户创建接口)无需添加顶层字段即可正常运行,相关代码如下:
# generate a user account helper function def generate_user_account( user_id, account_type = "online", account_email = str(get_datetime_now_iso()) + "@email.com", account_provider = "google", used_for="PERSONAL" ): return { "user_id": user_id, "account_type": account_type, "account_email": account_email, "account_provider": account_provider, "used_for": used_for } # create a user account helper function def create_user_account(payload, headers): return requests.post(API_ENDPOINT + "/account", headers=headers, json=payload) # User creation / registration route @router.post("/", response_model=schemas.User) def create_user( user_to_create: schemas.UserCreate, db: Session = Depends(deps.get_db) ): return user.create_user(db=db, user=user_to_create) # schemas class UserBase(BaseModel): username: str email: str timezone: str class UserCreate(UserBase): password: str
原因分析
这不是操作错误,是FastAPI的参数解析规则导致的差异:
- 当接口函数只有一个请求体模型参数(比如用户创建接口的
user_to_create),FastAPI会自动把整个请求体JSON解析到这个模型中,不需要额外的顶层键。 - 当接口函数同时存在请求体模型参数和其他依赖参数(比如日历接口的
user_calendar加上current_user、db),FastAPI默认会要求请求体JSON嵌套在以该模型参数名为键的顶层字段里(也就是user_calendar),这就是你遇到错误的原因。
统一处理方案
要保持所有接口的请求格式一致,推荐修改日历接口的路由参数,给user_calendar加上Body(...)装饰器,明确告诉FastAPI将整个请求体解析到该模型:
from fastapi import Body # Add User Calendar @router.post("", response_model=schemas.UserCalendar) async def add_user_calendar( user_calendar: schemas.UserCalendarBase = Body(...), # 添加Body(...) current_user: schemas.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), parent_slot: schemas.ParentSlot = None ): return usercalendar.add_user_calendar(user_calendar, current_user, db, parent_slot)
修改后,你就可以恢复原来的generate_user_calendar函数,不需要额外添加顶层键,和其他接口保持一致的请求格式。
内容的提问来源于stack exchange,提问作者peetysmith
相关产品推荐
相关产品推荐

