如何在pydantic模式验证后从snake案例转变为camel案例

2024-10-03 17:25:15 发布

您现在位置:Python中文网/ 问答频道 /正文

通过使用Alias Generator,我可以找到一种方法将基于camelcase类型的请求体转换为snake-case-one,但是对于我的响应,我再次希望将snake-case-type转换为camelcase-type-post-to-schema验证。我有什么办法可以做到这一点吗

例如: 我确实有一个python dict,如下所示

{
 "title_name": "search001",
 "status_type": "New" 
}

在pydantic模式验证后,我的dict应该将snake-case类型转换为camel-case,如下所示

{
 "titleName": "search001",
 "statusType": "New" 
}

如何定义pydantic模式来实现上述问题

提前谢谢


Tags: 方法类型newtype模式aliasgeneratorpost
3条回答

您可以使用Alias Generator

from pydantic import BaseModel


def to_snake_case(string: str) -> str:
    return ''.join(['_' + i.lower() if i.isupper() else i for i in string]).lstrip('_')


class MyModel(BaseModel):
    titleName: str
    statusType: str

    class Config:
        alias_generator = to_snake_case


data = {
    "title_name": "search001",
    "status_type": "New"
}
print(MyModel(**data).dict()) # {'titleName': 'search001', 'statusType': 'New'}

我强烈建议你可以试试这个。使用marshmallow

from marshmallow import Schema, fields


def camelcase(s):
    parts = iter(s.split("_"))
    return next(parts) + "".join(i.title() for i in parts)


class CamelCaseSchema(Schema):
    """Schema that uses camel-case for its external representation
    and snake-case for its internal representation.
    """

    def on_bind_field(self, field_name, field_obj):
        field_obj.data_key = camelcase(field_obj.data_key or field_name)


#                                       -


class UserSchema(CamelCaseSchema):
    first_name = fields.Str(required=True)
    last_name = fields.Str(required=True)


schema = UserSchema()
loaded = schema.load({"firstName": "David", "lastName": "Bowie"})
print(loaded)  # => {'last_name': 'Bowie', 'first_name': 'David'}
dumped = schema.dump(loaded)
print(dumped)  # => {'lastName': 'Bowie', 'firstName': 'David'}

你可以在那里学到更多

您可以结合使用别名生成器和.json.dict中的kwargby_alias

from pydantic import BaseModel,Field

def to_camel(string: str) -> str:
    string_split = string.split('_')
    return string_split[0]+''.join(word.capitalize() for word in string_split[1:])


class Foo(BaseModel):
    title_name:str
    status_type:str
    class Config:
        alias_generator = to_camel

f = Foo.parse_raw("""
{
 "titleName": "search001",
 "statusType": "New" 
}
""")
print(f) # title_name='search001' status_type='New'
print(f.json(by_alias=True)) # {"titleName": "search001", "statusType": "New"}
print(f.json()) # {"title_name": "search001", "status_type": "New"}

此外,还可以在Config类中添加allow_population_by_field_name=True,以便使用原始字段名或别名解析/初始化模型

相关问题 更多 >