我有这个型号:
class Text(BaseModel):
id: str
text: str = None
class TextsRequest(BaseModel):
data: list[Text]
n_processes: Union[int, None]
所以我希望能够接受这样的请求:
{"data": ["id": "1", "text": "The text 1"], "n_processes": 8}
和
{"data": ["id": "1", "text": "The text 1"]}.
现在在第二种情况下,我得到
{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}
使用此代码:
app = FastAPI()
@app.post("/make_post/", response_model_exclude_none=True)
async def create_graph(request: TextsRequest):
input_data = jsonable_encoder(request)
那么,如何在此处排除n_processes
?
由于Pydantic>=2.0弃用model.dict((,改为使用model.model_dump(...)
您可以使用Pydantic模型的exclude_none
参数。dict(…(:
class Text(BaseModel):
id: str
text: str = None
class TextsRequest(BaseModel):
data: list[Text]
n_processes: Optional[int]
request = TextsRequest(**{"data": [{"id": "1", "text": "The text 1"}]})
print(request.dict(exclude_none=True))
输出:
{'data': [{'id': '1', 'text': 'The text 1'}]}
此外,编写Optional[int]
而不是Union[int, None]
更为惯用。
Pydantic为使用model.dict(...)
方法导出模型提供了以下参数(Update:此方法最近已被model.model_dump(...)
取代(:
exclude_unset
:当创建模型应该从返回的字典中排除;默认False
exclude_none
:等于None的字段是否应该从返回的词典中排除;默认False
由于您指的是排除可选的未设置参数,因此可以使用第一种方法(即exclude_unset
(。如果要仅排除参数(如果该参数未设置为某个值或None
(,则此选项非常有用。
然而,exclude_none
参数忽略了一个事实,即属性可能已被有意设置为None
,因此将其从返回的字典中排除。
示例:
from pydantic import BaseModel
from typing import List, Union
class Text(BaseModel):
id: str
text: str = None
class TextsRequest(BaseModel):
data: List[Text] # in Python 3.9+ you can use: data: list[Text]
n_processes: Union[int, None] = None
t = TextsRequest(**{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None})
print(t.dict(exclude_none=True))
#> {'data': [{'id': '1', 'text': 'The text 1'}]}
print(t.dict(exclude_unset=True))
#> {'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}
关于可选参数
使用Union[int, None]
与使用Optional[int]
是相同的(两者都是等效的(。然而,使参数可选的最重要的部分是= None
部分。
根据FastAPI文档(请参阅提供的链接中的警告注意和信息(:
注意
FastAPI将知道
q
的值不是必需的,因为默认值CCD_ 20。
Union[str, None]
中的Union
将允许您的编辑器为您提供更好地支持和检测错误。
信息
请记住,使参数可选的最重要部分是部分:
= None
,因为它将使用None
作为默认值,这样就使得参数不是必需的。
Union[str, None]
部分允许您的编辑器提供更好的支持,但这不是告诉FastAPI该参数是不需要。
因此,无论您选择使用哪个选项,如果后面没有= None
部分,FastAPI都不会知道参数的值是可选的,因此,用户将必须为其提供一些值。您也可以通过http://127.0.0.1:8000/docs,其中parameter
或request body
将显示为Required
字段。
例如,以下任何一项都将要求用户在其对TextsRequest
模型的请求中传递一些body
内容:
@app.post("/upload")
def upload(t: Union[TextsRequest, None]):
pass
@app.post("/upload")
def upload(t: Optional[TextsRequest]):
pass
但是,如果上述TextsRequest
定义被= None
继承,例如:
@app.post("/upload")
def upload(t: Union[TextsRequest, None] = None):
pass
@app.post("/upload")
def upload(t: Optional[TextsRequest] = None):
pass
@app.post("/upload")
def upload(t: TextsRequest = None): # this should work as well
pass
参数(或主体(将是可选,因为= None
将告诉FastAPI该参数是-不需要。
在Python 3.10中+
好消息是,在Python 3.10及更高版本中,您不必担心Optional
和Union
这样的名称,因为您可以简单地使用竖条|
(也称为位或运算符,但这一含义在这里无关(来定义可选参数(或简单地说,类型的并集(但是,同样的规则也适用于此选项,即如果您想使参数可选,则仍然需要添加= None
部分(如下面给出的示例所示(。
示例:
@app.post("/upload")
def upload(t: TextsRequest | None = None):
pass
您可以使用response_model_exclude_unset
而不是response_model_exlclude_none
app = FastAPI()
@app.post("/make_post/", response_model_exclude_unset=True)
async def create_graph(request: TextsRequest):
input_data = jsonable_encoder(request)