Как переименовать атрибут в сериализторах pydantic?
Есть подобная модель:
from pydantic import BaseModel
class SomeModel(BaseModel):
attr1: str
attr2: str
attr3: str
Мне необходимо на выходе получить:
{ attr_1: "someText", attr_2: "someText", attr_3: "someText" }
Я знаю, что в marshmallow есть для этого параметр attribute, есть ли что-то подобное в pydantic?
Пробовал alias, но, кажется, это другое.
Ответы (1 шт):
Именно через alias. Пример:
from pydantic import BaseModel, Field
class SomeModel(BaseModel):
attr1: str = Field(alias="attr_1")
attr2: str = Field(alias="attr_2")
attr3: str = Field(alias="attr_3")
class Config:
allow_population_by_field_name = True
some_model = SomeModel(attr1="someText", attr2="someText", attr3="someText")
print(some_model) # attr1='someText' attr2='someText' attr3='someText'
print(some_model.json(by_alias=True)) # {"attr_1": "someText", "attr_2": "someText", "attr_3": "someText"}
Вывод:
attr1='someText' attr2='someText' attr3='someText'
{"attr_1": "someText", "attr_2": "someText", "attr_3": "someText"}
Настройка allow_population_by_field_name = True тут используется, чтобы при создании объекта SomeModel(attr1="someText", attr2="someText", attr3="someText") можно было указывать внутренние имена атрибутов (по умолчанию при наличии псевдонима при создании объекта нужно указывать псевдонимы атрибутов).
Также, чтобы создавать псевдонимы автоматически, в Config можно указать функцию преобразования имен в псевдонимы, пример:
import re
def alias_generator(name: str):
return '_'.join(re.search(r"([a-zA-Z]+)(\d+)", name).groups())
class SomeModel(BaseModel):
attr1: str
attr2: str
attr3: str
class Config:
alias_generator = alias_generator
allow_population_by_field_name = True
some_model = SomeModel(attr1="someText", attr2="someText", attr3="someText")
print(some_model)
print(some_model.json(by_alias=True))
Можно также использовать готовый пакет pyhumps, который умеет преобразовывать snake_case в camelCase или PascalCase и обратно (но правда не умеет преобразовывать attr1 в attr_1, поэтому в предыдущем примере пришлось писать свою функцию). Пример:
import humps
class SomeModel(BaseModel):
attr_one: str
attr_two: str
attr_three: str
class Config:
alias_generator = humps.camelize
allow_population_by_field_name = True
some_model = SomeModel(attr_one="someText", attr_two="someText", attr_three="someText")
print(some_model)
print(some_model.json(by_alias=True))
Вывод:
attr_one='someText' attr_two='someText' attr_three='someText'
{"attrOne": "someText", "attrTwo": "someText", "attrThree": "someText"}`
Полезная статья: CamelCase Models with FastAPI and Pydantic