首页 > 解决方案 > jsons数组的Pydantic模型

问题描述

我正在使用 FastAPI 编写 Web 服务。它又好又快。

FastAPI 使用 pydantic 模型来验证输入和输出数据,一切都很好,但是当我想为 jsons 数组声明一个嵌套模型时,如下所示:

[
   {
      "name": "name1",
      "family": "family1"
   },
   {
      "name": "name2",
      "family": "family2"
   }
]

我得到空洞的回应。

我认为我的模型存在问题:

class Test(BaseModel):
    name: str
    family: str
    class Config:
        orm_mode = True

class Tests(BaseModel):
    List[Test]
    class Config:
        orm_mode = True

所以,我的问题是我应该如何为 jsons 数组编写模型?

标签: pythonfastapipydantic

解决方案


更新(2020 年 9 月 26 日)

在 Python 3.9(尚未发布)中,您可以执行以下相同操作,但使用内置list泛型类型(始终在范围内),而不需要从 导入大写List类型typing,例如

@app.get("/tests", response_model=list[Test])

这里的问题是您正在尝试创建一个不需要的pydantic模型。如果你想序列化/反序列化一个对象列表,只需将你的奇异模型包装在List[]python 的内置typing模块中。无需尝试使用pydantic BaseModel创建对象的复数版本(如您所见,它无论如何都不起作用)。

话虽如此,做你想做的最简单的方法就是List[Test]在你需要s列表的任何地方指定a Test,例如

from typing import List

from fastapi import FastAPI
from pydantic import BaseModel


existing_tests = [
    {
        "name": "name1",
        "family": "family1"
    },
    {
        "name": "name2",
        "family": "family2"
    }
]


class Test(BaseModel):
    name: str
    family: str

    class Config:
        orm_mode = True


app = FastAPI()


@app.get("/tests", response_model=List[Test])
async def fetch_tests():
    return existing_tests


@app.post("/tests")
async def submit_tests(new_tests: List[Test]):
    print(new_tests)

但是当然,如​​果您发现自己反复(或仅)指定Test为列表,您当然可以将其分配给一个变量,然后在需要时使用该变量,如下所示:

Tests = List[Test]

@app.get("/tests", response_model=Tests)
async def fetch_tests():
    return existing_tests

@app.post("/tests")
async def submit_tests(new_tests: Tests):
    print(new_tests)

我认为第一个选项在您的代码中可能稍微清晰一些,除非您List[Test]多次指定,否则为此目的使用变量可能不值得额外的间接层。


推荐阅读