【问题标题】:Pydantic models good practice in FastAPIPydantic 为 FastAPI 中的良好实践建模
【发布时间】:2021-09-24 03:39:55
【问题描述】:

我正在使用 FastAPI 构建一个 REST API,我非常喜欢这个工具,尤其是与 Pydantic 和 OpenAPI 的集成。

例如,我可以将端点采用的模型写为

class Model(BaseModel):
    field1: str = Field(default=...)
    field2: int = Field(default=...)
    field3: List[int] = Field(default=...)
    field4: float = Field(default=...)
    class Config:
        schema_extra = {
            "example": {
                'field1': 'example 1',
                'field2': 1,
                'field3': [1, 2],
                'field4': 1.3,
            }
        }

但是我发现我的代码中有很多重复项,例如,如果我想创建另一个继承自 Model 的类并添加另一个字段 field5,我需要重新编写 Config 类为了定义新的例子。

有什么好的方法吗?例如,是否有任何工具允许您定义具有所有属性和示例的字段,然后根据需要包含的定义创建类 Model

也欢迎任何其他更适合此的模式。

【问题讨论】:

    标签: python fastapi pydantic


    【解决方案1】:

    您可以额外创建一个基本架构并在每个实例中进行修改:

    base_schema_extra = {
        "example": {
            'field1': 'example 1',
            'field2': 1,
            'field3': [1, 2],
            'field4': 1.3,
        }
    }
    
    class Model(BaseModel):
        field1: str = Field(default=...)
        field2: int = Field(default=...)
        field3: List[int] = Field(default=...)
        field4: float = Field(default=...)
    
        class Config:
            schema_extra = base_schema_extra
    
    
    class Model2(BaseModel):
        field1: str = Field(default=...)
        field2: int = Field(default=...)
        field3: List[int] = Field(default=...)
        field4: float = Field(default=...)
        field5: bool = Field(default=...)
    
        class Config:
            schema_extra = dict(**base_schema_extra, **{'field5': True})
    

    您还可以使用以下方法继承类:

    class Model3(Model2):
        field6: bool = Field(default=...)
    
        class Config(Model.Config):
            schema_extra = dict(**Model.Config.schema_extra, **{'field6': False})
    

    【讨论】:

    • 谢谢,这正是我正在做的。我仍然觉得应该有更好的方法来做到这一点
    • 你看到我的第三个建议了吗? (Model3) @GZZ --> 不幸的是,这似乎是创建继承多个模型的 pydantic 模型的挑战。可能与diamond inheritance 冲突有关。
    【解决方案2】:

    声明另一个继承自 Base Model 类的类。添加另一个字段。 Config 将保持不变,但多了一个示例字段。

    class ChildModel(Model):
        field5: str = Field(default=...)
        class Config:
            schema_extra = {
                "example": {
                    'field1': 'example 1',
                    'field2': 1,
                    'field3': [1, 2],
                    'field4': 1.3,
                    'field5': 'foo'
                }
            }
    

    它会工作,没问题

    【讨论】:

    • 感谢您的回答,但这正是我在帖子中所指的。您必须为所有字段重新定义示例。
    猜你喜欢
    • 2014-12-08
    • 2021-05-26
    • 2011-08-08
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多