我是FastAPI的新手(从Flask迁移(,我正在尝试为我的GET
路由创建Pydantic模型:
from fastapi import APIRouter,Depends
from pydantic import BaseModel
from typing import Optional,List
router = APIRouter()
class SortModel(BaseModel):
field: Optional[str]
directions: List[str]
@router.get("/pydanticmodel")
def get_sort(criteria: SortModel = Depends(SortModel)):
pass #my code for handling this route.....
当我运行curl -X GET http://localhost:XXXX/pydanticmodel?directions=up&directions=asc&field=id
时,我得到的是422 Unprocessable Entity: {"detail":[{"loc":["body"],"msg":"field required","type":"value_error.missing"}]}
但是如果我正在改变directions:List[str]
->directions: str
我用directions="asc"
得到200 OK
。str
适用于查询参数而List[str]
不适用的原因是什么?我做错了什么?
谢谢。
到目前为止,还不可能使用带有PydanticList
字段作为query
参数的GET
请求。当您在Pydantic模型中声明List
字段时,它被解释为请求body
参数,而不是query
参数(无论使用Depends()
如何——您可以通过Swagger UI文档在http://127.0.0.1:8000/docs例如(。此外,当您使用GET
请求时,即使您在body
中添加了directions
的List
并尝试发送请求,它也不会起作用,因为该操作需要POST
请求。
实现这一点的方法是显式定义directions
的List
,并将Query
作为端点中的一个单独参数,或者在一个单独的依赖类中实现查询参数解析,如下所述。再次记住,使用Query
显式定义List
字段,以便directions
可以被解释为查询参数,并在URL中多次出现(换句话说,接收多个值(。示例:
from typing import List, Optional
from fastapi import APIRouter, Depends, Query
class SortModel:
def __init__(
self,
field: Optional[str],
directions: List[str] = Query(...)
):
self.field = field
self.directions = directions
router = APIRouter()
@router.get("/")
def send_user(criteria: SortModel = Depends()):
return criteria
以上内容可以使用@dataclass
装饰器重写,如下所示:
from typing import List, Optional
from fastapi import APIRouter, Depends, Query
from dataclasses import dataclass
@dataclass
class SortModel:
field: Optional[str]
directions: List[str] = Query(...)
router = APIRouter()
@router.get("/")
def send_user(criteria: SortModel = Depends()):
return criteria
更新
现在可以将Query()
封装在Field()
中,这将允许您定义一个PydanticList
字段,该字段将被解释为查询参数。有关工作示例,请参见此答案。
我遇到了同样的问题。以下解决方案会起作用,但这并不是我真正想要的,但也许它对你来说已经足够好了:
from fastapi import APIRouter,Depends, Query
from pydantic import BaseModel
from typing import Optional,List
router = APIRouter()
class SortModel(BaseModel):
field: Optional[str]
@router.get("/pydanticmodel")
def get_sort(criteria: SortModel = Depends(SortModel), directions: List[str] = Query(...)):
pass #my code for handling this route.....
这不是Pydantic或FastAPI问题。
如果要发送带有curl的数组,则应使用-d标志。
In: curl -X GET "http://127.0.0.1:8000/pydanticmodel?field=123" -d "["string"]"
Out: {"field":"123","directions":["string"]}
现在您的代码应该可以完美地工作了。