[英]How to exclude Optional unset values from a Pydantic model using FastAPI?
I have this model:我有这个 model:
class Text(BaseModel):
id: str
text: str = None
class TextsRequest(BaseModel):
data: list[Text]
n_processes: Union[int, None]
So I want to be able to take requests like:所以我希望能够接受如下请求:
{"data": ["id": "1", "text": "The text 1"], "n_processes": 8}
and和
{"data": ["id": "1", "text": "The text 1"]}.
Right now in the second case I get现在在第二种情况下我得到
{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}
using this code:使用此代码:
app = FastAPI()
@app.post("/make_post/", response_model_exclude_none=True)
async def create_graph(request: TextsRequest):
input_data = jsonable_encoder(request)
So how can I exclude n_processes
here?那么如何在这里排除n_processes
呢?
You can use exclude_none
param of dict() :您可以使用dict()的exclude_none
参数:
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))
Output: Output:
{'data': [{'id': '1', 'text': 'The text 1'}]}
Also, it's more idiomatic to write Optional[int]
instead of Union[int, None]
此外,写Optional[int]
而不是Union[int, None]
更惯用
Pydantic provides the following arguments for exporting models using the model.dict(...)
method: Pydantic 提供以下 arguments 用于使用model.dict(...)
方法导出模型:
exclude_unset
: whether fields which were not explicitly set when creating the model should be excluded from the returned dictionary;exclude_unset
:是否应从返回的字典中排除在创建 model 时未明确设置的字段; defaultFalse
默认False
exclude_none
: whether fields which are equal to None should be excluded from the returned dictionary;exclude_none
:是否应该从返回的字典中排除等于 None 的字段; defaultFalse
默认False
Since you are refering to excluding optional unset parameters, you can use the first method (ie, exclude_unset
).由于您指的是排除可选的未设置参数,因此您可以使用第一种方法(即exclude_unset
)。 This is useful when one would like to exclude a parameter only if it has not been set to either some value or None
.当一个参数没有设置为某个值或None
时,这很有用。
The exclude_none
argument, however, ignores that fact that an attribute may have been intentionally set to None
, and hence, excludes it from the returned dictionary.但是, exclude_none
参数忽略了一个属性可能已被有意设置为None
的事实,因此将其从返回的字典中排除。
Example:例子:
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}
Using Union[int, None]
is the same as using Optional[int] = None
or int | None
使用Union[int, None]
与使用Optional[int] = None
或int | None
相同。 int | None
(in Python 3.10+). int | None
(在 Python 3.10+ 中)。 However, as per FastAPI documentation (see admonition Note and Info in the link provided):但是,根据FastAPI 文档(请参阅提供的链接中的警告说明和信息):
Note笔记
FastAPI will know that the value of
q
is not required because of the default value= None
. FastAPI 将知道q
的值不是必需的,因为默认值= None
。The
Union
inUnion[str, None]
will allow your editor to give you better support and detect errors.Union
Union[str, None]
中的 Union 将允许您的编辑器为您提供更好的支持并检测错误。
Info信息
Have in mind that the most important part to make a parameter optional is the part:
= None
, as it will use thatNone
as the default value, and that way make the parameter not required .请记住,使参数成为可选的最重要部分是 part:= None
,因为它将使用None
作为默认值,并且这样使参数不是 required 。The
Union[str, None]
part allows your editor to provide better support, but it is not what tells FastAPI that this parameter is not required .Union[str, None]
部分允许您的编辑器提供更好的支持,但这并不是告诉 FastAPI这个参数不是必需的。
Hence, regardless of the option (ie, Union
, Optional
, etc.) one may decide to use, if it is not followed by the = None
part, FastAPI won't know that the value of the parameter is not required , and hence, the user will have to provide some value for it.因此,无论选项(即Union
、 Optional
等)如何决定使用,如果它后面= None
部分,FastAPI 将不知道参数的值是不需要的,因此,用户必须为其提供一些价值。 One can also check this through the auto-generated API docs at http://127.0.0.1:8000/docs , where the parameter
or request body
will appear as a Required
field.也可以通过自动生成的 API 文档在http://127.0.0.1:8000/docs中检查这一点,其中parameter
或request body
将显示为Required
字段。
For example:例如:
@app.post("/upload")
def upload(t: Union[TextsRequest, None]):
def upload(t: Optional[TextsRequest]):
def upload(t: TextsRequest | None):
any of the above would require the user to pass some body for the TextsRequest
model in their request.以上任何一项都需要用户在他们的请求中为TextsRequest
model 传递一些正文。 If, however, the above TextsRequest
definitions were succeeded by = None
(eg, t: Union[TextsRequest, None] = None
, or even simply t: TextsRequest = None
), the parameter
or body
would be optional
(as = None
would tell FastAPI that this parameter is not required ).但是,如果上面的TextsRequest
定义由= None
成功(例如, t: Union[TextsRequest, None] = None
,或者甚至只是t: TextsRequest = None
),则parameter
或body
将是optional
的(因为= None
会告诉FastAPI 表示此参数不是必需的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.