是否可以更改 pydantic 中的输出别名?

Rec*_*chu 34 python json json-deserialization pydantic fastapi

设置:

# 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())
Run Code Online (Sandbox Code Playgroud)

问题:
创建响应时使用别名,我想避免它。我只需要这个别名来正确映射传入数据,但在返回响应时,我想使用实际的字段名称。

实际响应:

{
  "categories": [
    {
      "strCategory": "Beef",
      "strCategoryDescription": "Beef is ..."
    },
    {
      "strCategory": "Chicken",
      "strCategoryDescription": "Chicken is ..."
    }
}
Run Code Online (Sandbox Code Playgroud)

预期回应:

{
  "categories": [
    {
      "name": "Beef",
      "description": "Beef is ..."
    },
    {
      "name": "Chicken",
      "description": "Chicken is ..."
    }
}
Run Code Online (Sandbox Code Playgroud)

Her*_*cón 48

更新(2023-10-07):检查问题中的评论以获取其他答案,并在同一问题中查看 pydantic 2.0 或更高版本的答案。


切换别名和字段名称并使用allow_population_by_field_name 模型配置选项:

class TMDB_Category(BaseModel):
    strCategory: str = Field(alias="name")
    strCategoryDescription: str = Field(alias="description")

    class Config:
        allow_population_by_field_name = True
Run Code Online (Sandbox Code Playgroud)

让别名配置您想要返回的字段的名称,但能够allow_population_by_field_name解析使用不同字段名称的数据。

  • 考虑到您所展示的设置。我以后可以通过别名在代码中访问这些属性吗?例如,解析后: `r = TMDB_GetCategoriesResponse.parse_obj(response.json())` `print(r.name)` `print(r.description)` 还是我将被迫使用这些可怕的 `r.strCategory`和 `r.strCategoryDe​​scription` (2认同)

Sea*_*ean 12

使用配置选项by_alias


from fastapi import FastAPI, Path, Query
from pydantic import BaseModel, Field

app = FastAPI()

class Item(BaseModel):
    name: str = Field(..., alias="keck")

@app.post("/item")
async def read_items(
    item: Item,
):
    return item.dict(by_alias=False)
Run Code Online (Sandbox Code Playgroud)

鉴于请求:

{
  "keck": "string"
}
Run Code Online (Sandbox Code Playgroud)

这将返回

{
  "name": "string"
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您在路由器配置中设置了“response_model”,则这将不起作用。正如OP所言,`@router.get(path="category", response_model=TMDB_GetCategoriesResponse)`响应字段名称将不同,并会导致它在返回响应时验证失败 (2认同)

小智 5

你需要改变alias才能拥有validation_alias

class TMDB_Category(BaseModel):
    name: str = Field(validation_alias="strCategory")
    description: str = Field(validation_alias="strCategoryDescription")
Run Code Online (Sandbox Code Playgroud)

可以使用 来设置序列化别名serialization_alias文档