我试图有一个像
/services?status=New
这样的端点
status
将是 New
或 Old
这是我的代码:
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from enum import Enum
router = APIRouter()
class ServiceStatusEnum(str, Enum):
new = "New"
old = "Old"
class ServiceStatusQueryParam(BaseModel):
status: ServiceStatusEnum
@router.get("/services")
def get_services(
status: ServiceStatusQueryParam = Query(..., title="Services", description="my desc"),
):
pass #my code for handling this route.....
结果是我收到一个似乎与此问题相关的错误here
错误提示
AssertionError: Param: status can only be a request body, using Body()
然后我找到了另一个解释的解决方案here。
所以,我的代码将是这样的:
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from enum import Enum
router = APIRouter()
class ServiceStatusEnum(str, Enum):
new = "New"
old = "Old"
class ServicesQueryParam(BaseModel):
status: ServiceStatusEnum
@router.get("/services")
def get_services(
q: ServicesQueryParam = Depends(),
):
pass #my code for handling this route.....
它正在工作(我不明白为什么) - 但问题是如何以及在哪里添加描述和标题?
要创建 Pydantic 模型并使用它来定义查询参数,您需要将
Depends()
与端点中的参数一起使用。要添加 description
、title
等来查询参数,您可以将 Query()
包装在 Field()
中。
还应该注意的是,可以使用
Literal
类型代替 Enum
,如here和here所述。此外,如果想在 Pydantic 模型中定义 List
字段并将其用作查询参数,他们要么需要在单独的依赖类中实现此功能,如 here 和 here 所示,或者再次将 Query()
包裹在 Field()
中,如下所示。
此外,要对 Pydnatic 模型内的查询参数进行验证,可以像往常一样使用 Pydantic 的
@validator
来执行此操作,如 here、here 和 here 所示。 注意,在这种情况下,BaseModel
用于查询参数,提高ValueError
将导致Internal Server Error
。因此,您应该在验证失败时引发 HTTPException
,或者使用自定义异常处理程序,以处理 ValueError
异常,如 this answer 的选项 2 所示。除了 @validator
之外,还可以对 Query
参数进行额外验证,如 FastAPI 文档 中所述(另请参阅 Query
类实现)。
Optional
模块中的 None
类型提示(伴随 Query
作为
typing
中的默认值);但是,您可能还想查看这个答案和这个答案,它们描述了如何做到这一点的所有可用方法。
from fastapi import FastAPI, Depends, Query, HTTPException
from pydantic import BaseModel, Field, validator
from typing import List, Optional, Literal
from enum import Enum
app = FastAPI()
class Status(str, Enum):
new = 'New'
old = 'Old'
class ServiceStatus(BaseModel):
status: Optional[Status] = Field (Query(..., description='Select service status'))
msg: Optional[str] = Field (Query(None, description='Type something'))
choice: Literal['a', 'b', 'c', 'd'] = Field (Query(..., description='Choose something'))
comments: List[str] = Field (Query(..., description='Add some comments'))
@validator('choice')
def check_choice(cls, v):
if v == 'b':
raise HTTPException(status_code=422, detail='Wrong choice')
return v
@app.get('/status')
def main(status: ServiceStatus = Depends()):
return status
请注意,在 Pydantic V2 中,
@validator
已被弃用,并被 @field_validator
取代。请查看此答案以获取更多详细信息和示例。