带有列表输入的 FastAPI POST 请求引发 422 无法处理的实体错误
- 2025-03-04 08:27:00
- admin 原创
- 156
问题描述:
我想编写POST
一个输入参数为 的请求list
,但是出现错误422 unprocessable entity
:
{
"detail": [
{
"loc": [
"body"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
我的POST
要求是:
@router.post('',status_code=200)
def register(reg_id: int, reg_name: str, reg_option_list:List[int]):
reg_item = My_DB(
id=reg_id,
name=reg_name,
option_list=reg_option_list,
)
item = db.query(My_DB).filter(My_DB.id == service_id).first()
if item is not None:
raise HTTPException(status_code=400, detail="Item exists.")
db.add(reg_item)
db.commit()
return reg_item
但是,当我像下面这样更改代码,删除列表输入并将代码中的值设置为列表时,一切都正常:
@router.post('',status_code=200)
def register(reg_id: int, reg_name: str,):
reg_item = My_DB(
id=reg_id,
name=reg_name,
option_list=[1,2,3],
)
item = db.query(My_DB).filter(My_DB.id == service_id).first()
if item is not None:
raise HTTPException(status_code=400, detail="Item exists.")
db.add(reg_item)
db.commit()
return reg_item
我将非常感激任何有关我的list
输入参数的帮助。谢谢。
解决方案 1:
根据文档(请参阅“提示”部分)
要声明类型为 的查询参数
list
,如上例所示,您需要明确使用Query
,否则它将被解释为request body
。
List
因此,通过以您的方式声明参数,端点将期望在请求中接收它body
,而不是在查询字符串中作为query
参数接收它。因此,422 unprocessable entity
会引发错误,包括您提供的特定详细信息(即body
缺少字段)。您还可以通过 OpenAPI/Swagger UI 确认这一点/docs
,例如http://127.0.0.1:8000/docs
。您会看到的值reg_option_list
应该传递给Request body
部分,而不是在查询参数中。
选项 1 -List
在查询字符串中发送数据
实现此目的的方法是使用 ; 明确定义查询参数Query
,从而允许参数在 URL 中多次出现。由于这样的请求不包含请求主体,因此您应该使用请求GET
,它用于从服务器请求数据,而POST
用于将存储在请求主体中的数据发送到服务器。
例子
from fastapi import FastAPI, Query
from typing import List
app = FastAPI()
@app.get('/')
def register(reg_id: int, reg_name: str, reg_options: List[int] = Query(...)):
return reg_options
测试带Query
参数的List
URL :
http://127.0.0.1:8000/?reg_id=1®_name=foo®_options=1®_options=2®_options=3
使用 Python 请求进行测试:
import requests
url = 'http://127.0.0.1:8000/?reg_id=1®_name=foo®_options=1®_options=2®_options=3'
r = requests.get(url)
print(r.text)
或者,最好:
import requests
url = 'http://127.0.0.1:8000/'
params = {'reg_id': 1, 'reg_name': 'foo', 'reg_options': [1, 2, 3]}
r = requests.get(url, params=params)
print(r.text)
选项 2 -List
在请求正文中发送数据
如果您想使用POST
请求并在请求正文中发送数据,则可以简单地reg_options
以相同的方式定义上面的参数,但不使用该= Query(...)
部分。 这应该告诉 FastAPI 在请求正文中期望该端点的数据列表。 有关如何将请求正文中的数据发送到 FastAPI 后端的更多详细信息和示例,请查看此处以及此处和此处。 更多相关答案可以在这里、此处以及这里和这里找到。
扫码咨询,免费领取项目管理大礼包!