#python #json #fastapi #pydantic
#python #json #fastapi #pydantic
Вопрос:
Если я использую GET (с заданным идентификатором), я получаю 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"
}
в конкретном случае (если идентификатор не существует):
{
"data": {
"id": -1,
"ks": "",
"items": []
},
"server-time": "2021-12-10 09:35:22"
}
Я хотел бы создать Pydantic модель для управления этой структурой данных (я имею в виду формальное определение этих объектов).
Каков самый разумный способ управления этой структурой данных путем создания классов (возможно, вложенных)?
Ответ №1:
Если вам не нужна проверка данных, которая pydantic
предлагает, вы можете использовать классы данных вместе с dataclass-wizard
для этой же задачи. Это немного проще, поскольку вам не нужно определять сопоставление для ключей в оболочке lisp, таких как 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))
Комментарии:
1. Так
input_data
точно соответствует первому JSON, который я определил в своем вопросе? Чтобы получить JSON из объектаSomething
и наоборот, должны ли мы использоватьasdict()
иfromdict()
соответственно?2. @LJG Да, это правильно,
input_data
должно соответствовать JSON сверху. Я отметил, что ваши данные JSON в этом случае могут быть определены просто какdict
объект. Чтобы получить строку JSON, если таково намерение, вам нужно будет вызватьjson.dumps
asdict
результат, однако, если это более удобно, вы можете создать подкласс из класса JSONWizard mixin, как указано в документах, а затем можете просто использоватьto_json()
метод для прямого преобразования экземпляра в строку JSON.
Ответ №2:
Я вижу, что вы указали fastapi и pydantic, поэтому я бы посоветовал вам следовать официальному руководству, чтобы узнать, как работает fastapi. Здесь у вас есть целая часть, объясняющая использование pydantic с fastapi.
чтобы точнее ответить на ваш вопрос, модели 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")
Ответ №3:
Я рекомендую ознакомиться с официальным руководством для более подробного рассмотрения того, как фреймворк обрабатывает создание и проверку модели данных с помощью pydantic.
Чтобы ответить на ваш вопрос:
from datetime import datetime
from typing import List
from pydantic import BaseModel
class K(BaseModel):
k1: int
k2: int
class Item(BaseModel):
id: int
name: str
surname: str
class DataModel(BaseModel):
id: int = -1
ks: K = None
items: List[Item] = []
server_time: datetime = datetime.now()
Ответ №4:
from pydantic import BaseModel
class User(BaseModel):
id: int
name = "Jane Doe"
Комментарии:
1. Вопрос не задавался для какой -либо модели Pydantic. В вопросе был конкретный пример ввода, для которого требовались вложенные модели Pydantic.