设定:
# Pydantic Models
class TMDB_Category(BaseModel):
name: str = Field(alias="strCategory")
description: str = Field(alias="strCategoryDescription")
class TMDB_GetCategoriesResponse(BaseModel):
categories: list[TMDB_Category]
@router.get(path="category", response_model=TMDB_GetCategoriesResponse)
async def get_all_categories():
async with httpx.AsyncClient() as client:
response = await client.get(Endpoint.GET_CATEGORIES)
return TMDB_GetCategoriesResponse.parse_obj(response.json())
问题:
创建响应时使用了别名,我希望避免使用别名。我只需要此别名来正确Map传入数据,但在返回响应时,我希望使用实际的字段名称。
实际响应:
{
"categories": [
{
"strCategory": "Beef",
"strCategoryDescription": "Beef is ..."
},
{
"strCategory": "Chicken",
"strCategoryDescription": "Chicken is ..."
}
}
预期响应:
{
"categories": [
{
"name": "Beef",
"description": "Beef is ..."
},
{
"name": "Chicken",
"description": "Chicken is ..."
}
}
4条答案
按热度按时间nukf8bse1#
切换别名和字段名称,并使用
allow_population_by_field_name
model config选项:让别名配置您要返回的字段的名称,但要使
allow_population_by_field_name
能够解析使用不同字段名称的数据。mkshixfv2#
另一个选项(可能不会 * 那么流行 *)是使用一个反序列化库而不是
pydantic
。例如,Dataclass Wizard库就是一个支持这个特定用例的库。如果您需要Field(alias=...)
提供的相同的往返行为,您可以将all
参数传递给json_field
函数。注意,使用这样的库,您确实失去了执行完整类型验证的能力,而这可以说是Pydantic最大的优势之一;但是它会以类似于pydantic的方式执行类型转换。还有一些原因让我觉得验证并不那么重要,我在下面列出了这些原因。我认为数据验证是一个 * 很好拥有 * 的特性的原因:
为了演示这一点,下面是使用dataclass-wizard库(依赖于
dataclasses
的使用,而不是pydantic模型)的上述用例的一个简单示例:运行它的代码如下所示:
测量性能
如果有人好奇的话,我已经建立了一个快速基准测试,来比较pydantic和dataclasses的反序列化和序列化时间:
性能指标评测结果(在Mac OS Big Sur、Python 3.9.0上测试):
在他们的文档中,
pydantic
声称自己是最快的库,但是要证明它不是最快的库是相当简单的。正如你所看到的,对于上面的数据集,pydantic
在反序列化和序列化过程中大约慢2倍。值得注意的是,pydantic
已经相当快了。mw3dktmi3#
也许你可以用这种方法
ogq8wdun4#
我尝试做一些类似的事情(将字段
pattern
迁移到patterns
列表中,同时优雅地处理旧版本的数据)。我能找到的最好的解决方案是在__init__
方法中进行字段Map。用OP的术语来说,这将是这样的:然后我们有:
如果需要使用字段别名来实现这一点,但仍然在代码中使用名称/描述字段,一个选择是修改Hernán Alarcón的解决方案以使用属性:
这仍然有点尴尬,因为repr使用了“别名”: