定义 Pydantic(嵌套)模型

Define a Pydantic (nested) model

如果我使用 GET(给定一个 id),我会得到一个 JSON 比如:

{
    "data": {
        "id": "81",
        "ks": {
            "k1": 25,
            "k2": 5
        },
        "items": [
            {
                "id": 1,
                "name": "John",
                "surname": "Smith"
            },
            {
                "id": 2,
                "name": "Jane",
                "surname": "Doe"
            }
        ]
    },
    "server-time": "2021-12-09 14:18:40"
}

对于特定情况(如果 id 不存在):

{
    "data": {
        "id": -1,
        "ks": "",
        "items": []
    },
    "server-time": "2021-12-10 09:35:22"
}

我想创建一个 Pydantic 模型来管理这个数据结构(我的意思是正式定义这些对象)。 通过创建 类(可能是嵌套的)来管理这个数据结构的最聪明的方法是什么?

我看到你已经标记了 fastapi 和 pydantic,所以我建议你关注 official Tutorial to learn how fastapi work. You have a whole part explaining the usage of pydantic with fastapi here

为了更准确地回答您的问题,在 the doc 中很好地解释了 pydantic 模型。

简单的例子:

from typing import List
from pydantic import BaseModel

class Data(BaseModel):
    id: int
    ks: str
    items: List[str]

class Something(BaseModel):
    data: Data
    # you can replace it by a pydantic time type that fit your need
    server_time: str = Field(alias="server-time")
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name = "Jane Doe"

如果您不需要 pydantic 提供的数据验证,您可以将数据 类 与 dataclass-wizard 一起用于同一任务。它稍微容易一些,因为您不需要为 lisp-cased 键定义映射,例如 server-time.

下面的简单示例:

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime

from dataclass_wizard import fromdict


@dataclass
class Something:
    data: Data
    # or simply:
    #   server_time: str
    server_time: datetime


@dataclass
class Data:
    id: int
    ks: dict[str, int]
    items: list[Person]


@dataclass
class Person:
    id: int
    name: str
    surname: str


# note: data is defined in the OP above
input_data = ...

print(fromdict(Something, input_data))

输出:

Something(data=Data(id=81, ks={'k1': 25, 'k2': 5}, items=[Person(id=1, name='John', surname='Smith'), Person(id=2, name='Jane', surname='Doe')]), server_time=datetime.datetime(2021, 12, 9, 14, 18, 40))