You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10 KiB

Тіло - Вкладені моделі

З FastAPI ви можете визначати, перевіряти, документувати та використовувати моделі, які можуть бути вкладені на будь-яку глибину (завдяки Pydantic).

Поля списку

Ви можете визначити атрибут як підтип. Наприклад, Python-список (list):

{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}

Це зробить tags списком, хоча не визначається тип елементів списку.

Поля списку з параметром типу

Але Python має специфічний спосіб оголошення списків з внутрішніми типами або «параметрами типу»:

Оголошення list з параметром типу

Щоб оголосити типи з параметрами типу (внутрішніми типами), такими як list, dict, tuple, передайте внутрішні тип(и) як «параметри типу», використовуючи квадратні дужки: [ та ]

my_list: list[str]

Це стандартний синтаксис Python для оголошення типів.

Використовуйте той самий стандартний синтаксис для атрибутів моделей з внутрішніми типами.

Отже, у нашому прикладі, ми можемо зробити tags саме «списком строк»:

{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}

Типи множин

Але потім ми подумали, що теги не повинні повторюватися, вони, ймовірно, повинні бути унікальними строками.

І Python має спеціальний тип даних для множин унікальних елементів - це set.

Тому ми можемо оголосити tags як множину строк:

{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}

Навіть якщо ви отримаєте запит з дубльованими даними, він буде перетворений у множину унікальних елементів.

І коли ви будете виводити ці дані, навіть якщо джерело містить дублікати, вони будуть виведені як множина унікальних елементів.

І це буде анотовано / документовано відповідно.

Вкладені моделі

Кожен атрибут моделі Pydantic має тип.

Але цей тип сам може бути іншою моделлю Pydantic.

Отже, ви можете оголосити глибоко вкладені JSON «об'єкти» з конкретними іменами атрибутів, типами та перевірками.

Усе це, вкладене без обмежень.

Визначення підмоделі

Наприклад, ми можемо визначити модель Image:

{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}

Використання підмоделі як типу

А потім ми можемо використовувати її як тип атрибута:

{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}

Це означатиме, що FastAPI очікуватиме тіло, подібне до:

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2,
    "tags": ["rock", "metal", "bar"],
    "image": {
        "url": "http://example.com/baz.jpg",
        "name": "The Foo live"
    }
}

Знову ж, лише завдяки такому оголошенню, з FastAPI ви отримуєте:

  • Підтримку в редакторі (автозавершення тощо), навіть для вкладених моделей
  • Конвертацію даних
  • Валідацію даних
  • Автоматичну документацію

Спеціальні типи та валідація

Окрім звичайних одиничних типів, таких як str, int, float, та ін. ви можете використовувати складніші одиничні типи, які наслідують str.

Щоб побачити всі доступні варіанти, ознайомтеся з Оглядом типів у Pydantic. Деякі приклади будуть у наступному розділі.

Наприклад, оскільки в моделі Image є поле url, ми можемо оголосити його як екземпляр HttpUrl від Pydantic замість str:

{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}

Строку буде перевірено як дійсну URL-адресу і задокументовано в Схемі JSON / OpenAPI як таку.

Атрибути зі списками підмоделей

У Pydantic ви також можете використовувати моделі як підтипи для list, set тощо:

{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}

Це очікуватиме (конвертуватиме, валідуватиме, документуватиме тощо) тіло JSON у вигляді:

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2,
    "tags": [
        "rock",
        "metal",
        "bar"
    ],
    "images": [
        {
            "url": "http://example.com/baz.jpg",
            "name": "The Foo live"
        },
        {
            "url": "http://example.com/dave.jpg",
            "name": "The Baz"
        }
    ]
}

/// note | Примітка

Зверніть увагу, що тепер ключ images містить список об'єктів зображень.

///

Глибоко вкладені моделі

Ви можете визначати вкладені моделі довільної глибини:

{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}

/// note | Примітка

Зверніть увагу, що Offer має список Itemів, які, своєю чергою, мають необов'язковий список Imageів

///

Тіла запитів, що складаються зі списків

Якщо значення верхнього рівня JSON тіла, яке ви очікуєте, є JSON array (Python list), ви можете оголосити тип у параметрі функції так само, як у моделях Pydantic:

images: list[Image]

як у:

{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}

Підтримка в редакторі всюди

І ви отримаєте підтримку в редакторі всюди.

Навіть для елементів у списках:

Ви не змогли б отримати таку підтримку в редакторі, якби працювали напряму зі dict, а не з моделями Pydantic.

Але вам також не потрібно турбуватися про них: вхідні словники автоматично конвертуються, а вихідні дані автоматично перетворюються в JSON.

Тіла з довільними dict

Ви також можете оголосити тіло як dict з ключами одного типу та значеннями іншого типу.

Таким чином, вам не потрібно наперед знати, які імена полів/атрибутів є дійсними (як це було б у випадку з моделями Pydantic).

Це буде корисно, якщо ви хочете приймати ключі, які заздалегідь невідомі.


Інший корисний випадок - коли ви хочете мати ключі іншого типу (наприклад, int).

Ось що ми розглянемо тут.

У цьому випадку ви можете приймати будь-який dict, якщо він має ключі int зі значеннями float:

{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}

/// tip | Порада

Майте на увазі, що JSON підтримує лише str як ключі.

Але Pydantic має автоматичну конвертацію даних.

Це означає, що навіть якщо клієнти вашого API можуть надсилати лише строки як ключі, якщо ці строки містять цілі числа, Pydantic конвертує їх і проведе валідацію.

І dict, який ви отримаєте як weights, фактично матиме ключі типу int та значення типу float.

///

Підсумок

З FastAPI ви маєте максимальну гнучкість завдяки моделям Pydantic, зберігаючи при цьому код простим, коротким та елегантним.

Але з усіма перевагами:

  • Підтримка в редакторі (автозавершення всюди!)
  • Конвертація даних (також відома як парсинг / серіалізація)
  • Валідація даних
  • Документація схем
  • Автоматична документація