mirror of https://github.com/tiangolo/fastapi.git
🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/query-params-str-validations.md` page (#13546)
This commit is contained in:
parent
be6cfd6cf5
commit
e48c526b62
|
|
@ -0,0 +1,491 @@
|
|||
# Query параметри та валідація рядків
|
||||
|
||||
**FastAPI** дозволяє оголошувати додаткову інформацію та виконувати валідацію для Ваших параметрів.
|
||||
|
||||
Розглянемо цей додаток як приклад:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
|
||||
|
||||
Query параметр `q` має тип `str | None`, що означає, що він може бути як `str`, так і `None`. За замовчуванням він має значення `None`, тому FastAPI розуміє, що цей параметр не є обов'язковим.
|
||||
|
||||
/// note | Примітка
|
||||
|
||||
FastAPI знає, що `q` не є обов’язковим, завдяки значенню за замовчуванням `= None`.
|
||||
|
||||
Використання `str | None` дозволить Вашому редактору коду надавати кращу підтримку та виявляти помилки.
|
||||
|
||||
///
|
||||
|
||||
## Додаткова валідація
|
||||
|
||||
Ми хочемо, щоб навіть якщо `q` є необов’язковим, **його довжина не перевищувала 50 символів**, якщо він все ж буде переданий.
|
||||
|
||||
### Імпорт `Query` та `Annotated`
|
||||
|
||||
Щоб це зробити, спочатку імпортуємо:
|
||||
|
||||
* `Query` з `fastapi`
|
||||
* `Annotated` з `typing`
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
|
||||
|
||||
/// info | Інформація
|
||||
|
||||
FastAPI додав підтримку `Annotated` (і почав рекомендувати його) у версії 0.95.0.
|
||||
|
||||
Якщо у Вас старіша версія, під час використання `Annotated` можуть виникати помилки.
|
||||
|
||||
Переконайтеся, що Ви [оновили версію FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} до принаймні 0.95.1, перш ніж використовувати `Annotated`.
|
||||
|
||||
///
|
||||
|
||||
## Використання `Annotated` у типі параметра `q`
|
||||
|
||||
Пам’ятаєте, як я раніше розповідав, що `Annotated` можна використовувати для додавання метаданих до параметрів у [Вступі до типів Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}?
|
||||
|
||||
Зараз саме час використати його разом із FastAPI. 🚀
|
||||
|
||||
Раніше ми мали таку анотацію типу:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
q: Union[str, None] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Тепер ми загорнемо її у `Annotated`, і отримаємо:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
q: Annotated[str | None] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
q: Annotated[Union[str, None]] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Обидві ці версії означають одне й те саме: `q` — це параметр, який може бути `str` або `None`, і за замовчуванням має значення `None`.
|
||||
|
||||
А тепер переходимо до цікавого! 🎉
|
||||
|
||||
## Додавання `Query` до `Annotated` у параметр `q`
|
||||
|
||||
Тепер, коли у нас є `Annotated`, де ми можемо додавати додаткову інформацію (зокрема валідацію), додамо `Query` всередину `Annotated` і встановимо параметр `max_length` у `50`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
|
||||
|
||||
Зверніть увагу, що значення за замовчуванням усе ще `None`, тому параметр залишається необов'язковим.
|
||||
|
||||
Але тепер, додавши `Query(max_length=50)` всередину `Annotated`, ми повідомляємо FastAPI, що хочемо **додаткову валідацію** для цього значення — воно має містити максимум 50 символів. 😎
|
||||
|
||||
/// tip | Підказка
|
||||
|
||||
Ми використовуємо `Query()`, оскільки це **query параметр**. Далі ми розглянемо інші варіанти, як-от `Path()`, `Body()`, `Header()` та `Cookie()`, які приймають ті самі аргументи, що й `Query()`.
|
||||
|
||||
///
|
||||
|
||||
Тепер FastAPI:
|
||||
|
||||
* **Перевірить** дані, щоб переконатися, що їхня довжина не перевищує 50 символів
|
||||
* Покажe **чітку помилку** клієнту, якщо дані недійсні
|
||||
* **Задокументує** параметр в OpenAPI-схемі *операції шляху* (що відобразиться в **автоматично згенерованій документації**)
|
||||
|
||||
## Альтернативний (застарілий) метод: Query як значення за замовчуванням
|
||||
|
||||
У попередніх версіях FastAPI (до <abbr title="до 2023-03">0.95.0</abbr>) `Query` використовувався як значення за замовчуванням для параметра, а не всередині `Annotated`. Ви, ймовірно, побачите код, який використовує цей підхід, тому варто розглянути його.
|
||||
|
||||
/// tip | Підказка
|
||||
|
||||
Для нового коду та коли це можливо, використовуйте `Annotated`, як показано вище. Це має багато переваг (пояснених нижче) і не має недоліків. 🍰
|
||||
|
||||
///
|
||||
|
||||
Раніше ми писали `Query()` як значення за замовчуванням для параметра функції, встановлюючи `max_length` у 50:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
|
||||
|
||||
Оскільки в цьому випадку (без `Annotated`) нам потрібно замінити `None` у функції на `Query()`, тепер ми повинні явно встановити значення за замовчуванням через параметр `Query(default=None)`. Це виконує ту саму роль визначення значення за замовчуванням (принаймні для FastAPI).
|
||||
|
||||
Таким чином:
|
||||
|
||||
```Python
|
||||
q: str | None = Query(default=None)
|
||||
```
|
||||
|
||||
...робить параметр необов’язковим зі значенням за замовчуванням `None`, що еквівалентно:
|
||||
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
Але у версії з `Query` ми явно вказуємо, що це query параметр.
|
||||
|
||||
Далі ми можемо передавати `Query` додаткові параметри, зокрема `max_length`, який застосовується до рядків:
|
||||
|
||||
```Python
|
||||
q: str | None = Query(default=None, max_length=50)
|
||||
```
|
||||
|
||||
Це забезпечить валідацію даних, виведе зрозумілу помилку у разі недійсних даних і задокументує параметр у схемі OpenAPI *операції шляху*.
|
||||
|
||||
### `Query` як значення за замовчуванням або всередині `Annotated`
|
||||
|
||||
Важливо пам’ятати, якщо використовувати `Query` всередині `Annotated`, не можна задавати параметр `default` у `Query`.
|
||||
|
||||
Замість цього використовуйте значення за замовчуванням у самій функції. Інакше це буде нелогічно.
|
||||
|
||||
Наприклад, цей варіант є некоректним:
|
||||
|
||||
```Python
|
||||
q: Annotated[str, Query(default="rick")] = "morty"
|
||||
```
|
||||
|
||||
...тому, що не зрозуміло, яке значення має бути значенням за замовчуванням: `"rick"` чи `"morty"`.
|
||||
|
||||
Коректні варіанти:
|
||||
|
||||
```Python
|
||||
q: Annotated[str, Query()] = "rick"
|
||||
```
|
||||
|
||||
...або у старих кодових базах Ви знайдете:
|
||||
|
||||
```Python
|
||||
q: str = Query(default="rick")
|
||||
```
|
||||
|
||||
### Переваги використання `Annotated`
|
||||
|
||||
**Використання `Annotated` є рекомендованим** замість задання значення за замовчуванням у параметрах функції, оскільки воно **краще** з кількох причин. 🤓
|
||||
|
||||
Значення **за замовчуванням** параметра **функції** є його **фактичним значенням за замовчуванням**, що є більш інтуїтивним у Python загалом. 😌
|
||||
|
||||
Ви можете **викликати** ту саму функцію **в інших місцях** без FastAPI, і вона **працюватиме очікувано**. Якщо параметр є **обов’язковим** (без значення за замовчуванням), Ваш **редактор** повідомить про помилку, а **Python** також видасть помилку, якщо Ви виконаєте функцію без передавання цього параметра.
|
||||
|
||||
Якщо Ви не використовуєте `Annotated`, а використовуєте **(старий) стиль значень за замовчуванням**, то при виклику цієї функції без FastAPI **в інших місцях**, потрібно **не забути** передати їй аргументи, інакше значення будуть відрізнятися від очікуваних (наприклад, Ви отримаєте `QueryInfo` або подібне замість `str`). Ваш редактор не повідомить про помилку, і Python також не видасть помилку при запуску функції, поки не виникне помилка під час виконання операцій усередині.
|
||||
|
||||
Оскільки `Annotated` може містити кілька анотацій метаданих, Ви навіть можете використовувати ту саму функцію з іншими інструментами, такими як <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a>. 🚀
|
||||
|
||||
## Додавання додаткових валідацій
|
||||
|
||||
Ви також можете додати параметр `min_length`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
|
||||
|
||||
## Додавання регулярних виразів
|
||||
|
||||
Ви можете визначити <abbr title="Регулярний вираз (regex або regexp) — це послідовність символів, яка визначає шаблон для пошуку в рядках.">регулярний вираз</abbr> pattern, якому має відповідати параметр:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
||||
|
||||
Цей конкретний шаблон регулярного виразу перевіряє, що отримане значення параметра:
|
||||
|
||||
* `^`: починається з наступних символів, перед якими немає інших символів.
|
||||
* `fixedquery`: точно відповідає значенню `fixedquery`.
|
||||
* `$`: закінчується тут, після `fixedquery` немає жодних символів.
|
||||
|
||||
Якщо Ви почуваєтеся розгублено щодо **"регулярних виразів"**, не хвилюйтеся. Вони є складною темою для багатьох людей. Ви все одно можете зробити багато речей без їх використання.
|
||||
|
||||
Але тепер Ви знаєте, що коли вони знадобляться, їх можна застосовувати у **FastAPI**.
|
||||
|
||||
### Pydantic v1 `regex` замість `pattern`
|
||||
|
||||
До версії Pydantic 2 і FastAPI 0.100.0 параметр називався `regex` замість `pattern`, але тепер він застарів.
|
||||
|
||||
Ви все ще можете зустріти код, який використовує його:
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
|
||||
|
||||
////
|
||||
|
||||
Але майте на увазі, що він є застарілим і його слід оновити до нового параметра `pattern`. 🤓
|
||||
|
||||
## Значення за замовчуванням
|
||||
|
||||
Ви можете використовувати значення за замовчуванням, відмінні від `None`.
|
||||
|
||||
Наприклад, якщо Ви хочете оголосити параметр запиту `q` з `min_length` `3` і значенням за замовчуванням `"fixedquery"`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
|
||||
|
||||
/// note | Технічні деталі
|
||||
|
||||
Наявність значення за замовчуванням будь-якого типу, включаючи `None`, робить параметр необов’язковим (not required).
|
||||
|
||||
///
|
||||
|
||||
## Обов’язкові параметри
|
||||
|
||||
Якщо нам не потрібно вказувати додаткові перевірки або метадані, ми можемо зробити параметр `q` обов’язковим, просто не оголошуючи значення за замовчуванням, наприклад:
|
||||
|
||||
```Python
|
||||
q: str
|
||||
```
|
||||
|
||||
замість:
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
Але тепер ми оголошуємо його з `Query`, наприклад:
|
||||
|
||||
//// tab | Annotated
|
||||
|
||||
```Python
|
||||
q: Annotated[str | None, Query(min_length=3)] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Тому, якщо Вам потрібно зробити значення обов’язковим, використовуючи `Query`, просто не вказуйте значення за замовчуванням:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
|
||||
|
||||
### Обов’язкове значення, яке може бути `None`
|
||||
|
||||
Ви можете вказати, що параметр може приймати `None`, але при цьому залишається обов’язковим. Це змусить клієнтів надіслати значення, навіть якщо воно дорівнює `None`.
|
||||
|
||||
Щоб зробити це, оголосіть, що `None` є допустимим типом, але не вказуйте значення за замовчуванням:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
|
||||
|
||||
## Список параметрів запиту / кілька значень
|
||||
|
||||
Якщо Ви визначаєте параметр запиту за допомогою `Query`, Ви також можете дозволити отримання списку значень, тобто дозволити отримання кількох значень.
|
||||
|
||||
Наприклад, щоб дозволити параметру запиту `q` з'являтися кілька разів в URL, можна написати:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
|
||||
|
||||
Тоді, у випадку запиту за URL:
|
||||
|
||||
```
|
||||
http://localhost:8000/items/?q=foo&q=bar
|
||||
```
|
||||
|
||||
Ви отримаєте кілька значень *query параметра* `q` (`foo` і `bar`) у вигляді списку `list` в Python у Вашій *функції обробки шляху*, у *параметрі функції* `q`.
|
||||
|
||||
Отже, відповідь на цей URL буде:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"q": [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
/// tip | Підказка
|
||||
|
||||
Щоб оголосити параметр запиту з типом `list`, як у наведеному вище прикладі, потрібно явно використовувати `Query`, інакше він буде інтерпретований як тіло запиту.
|
||||
|
||||
///
|
||||
|
||||
Інтерактивна API-документація оновиться відповідно, дозволяючи передавати кілька значень:
|
||||
|
||||
<img src="/img/tutorial/query-params-str-validations/image02.png">
|
||||
|
||||
### Список параметрів запиту / кілька значень за замовчуванням
|
||||
|
||||
Ви також можете визначити значення за замовчуванням для `list`, якщо жодне значення не було передане:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
|
||||
|
||||
Якщо Ви перейдете за посиланням:
|
||||
|
||||
```
|
||||
http://localhost:8000/items/
|
||||
```
|
||||
|
||||
то значення `q` за замовчуванням буде: `["foo", "bar"]`, і Ваша відповідь виглядатиме так:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"q": [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Використання тільки `list`
|
||||
|
||||
Ви також можете використовувати `list` без уточнення типу, замість `list[str]`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
|
||||
|
||||
/// note | Технічні деталі
|
||||
|
||||
Майте на увазі, що в цьому випадку FastAPI не перевірятиме вміст списку.
|
||||
|
||||
Наприклад, `list[int]` перевірятиме (і документуватиме), що всі елементи списку є цілими числами. Але `list` без уточнення цього не робитиме.
|
||||
|
||||
///
|
||||
|
||||
## Додавання додаткових метаданих
|
||||
|
||||
Ви можете додати більше інформації про параметр.
|
||||
|
||||
Ця інформація буде включена у згенерований OpenAPI та використана в інтерфейсах документації та зовнішніх інструментах.
|
||||
|
||||
/// note | Технічні деталі
|
||||
|
||||
Майте на увазі, що різні інструменти можуть мати різний рівень підтримки OpenAPI.
|
||||
|
||||
Деякі з них можуть ще не відображати всю додаткову інформацію, хоча в більшості випадків ця функція вже запланована для розробки.
|
||||
|
||||
///
|
||||
|
||||
Ви можете додати `title` :
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
|
||||
|
||||
А також `description`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
|
||||
|
||||
## Аліаси параметрів
|
||||
|
||||
Уявіть, що Ви хочете, щоб параметр називався `item-query`.
|
||||
|
||||
Наприклад:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?item-query=foobaritems
|
||||
```
|
||||
|
||||
Але `item-query` — це некоректна назва змінної в Python.
|
||||
|
||||
Найближчий допустимий варіант — `item_query`.
|
||||
|
||||
Проте Вам потрібно, щоб параметр залишався саме `item-query`...
|
||||
|
||||
У такому випадку можна оголосити `alias`, і саме він буде використовуватися для отримання значення параметра:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
|
||||
|
||||
## Виведення параметрів як застарілих
|
||||
|
||||
Припустимо, що Ви більше не хочете використовувати цей параметр.
|
||||
|
||||
Вам потрібно залишити його на деякий час, оскільки ним користуються клієнти, але Ви хочете, щоб документація чітко показувала, що він є <abbr title="застарілий, не рекомендується до використання">застарілим</abbr>.
|
||||
|
||||
Тоді Ви можете передати параметр `deprecated=True` до `Query`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
|
||||
|
||||
Документація буде показувати це таким чином:
|
||||
|
||||
<img src="/img/tutorial/query-params-str-validations/image01.png">
|
||||
|
||||
## Виняток параметрів з OpenAPI
|
||||
|
||||
Щоб виключити параметр запиту зі згенерованої схеми OpenAPI (і, таким чином, з автоматичних систем документації), встановіть параметр `include_in_schema` для `Query` в `False`:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
|
||||
|
||||
## Кастомна валідація
|
||||
|
||||
Можуть бути випадки, коли Вам потрібно провести **кастомну валідацію**, яку не можна реалізувати за допомогою параметрів, показаних вище.
|
||||
|
||||
У таких випадках ви можете використати **кастомну функцію валідації**, яка буде застосована після звичайної валідації (наприклад, після перевірки, що значення є типом `str`).
|
||||
|
||||
Це можна досягти за допомогою <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantic's `AfterValidator`</a> в середині `Annotated`.
|
||||
|
||||
/// tip | Підказка
|
||||
|
||||
Pydantic також має <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> та інші. 🤓
|
||||
|
||||
///
|
||||
|
||||
Наприклад, цей кастомний валідатор перевіряє, чи починається ID елемента з `isbn-` для номера книги <abbr title="ISBN означає Міжнародний стандартний номер книги">ISBN</abbr> або з `imdb-` для ID URL фільму на <abbr title="IMDB (Internet Movie Database) це вебсайт з інформацією про фільми">IMDB</abbr>:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
||||
|
||||
/// info | Інформація
|
||||
|
||||
Це доступно з версії Pydantic 2 або вище. 😎
|
||||
|
||||
///
|
||||
|
||||
/// tip | Підказка
|
||||
|
||||
Якщо Вам потрібно виконати будь-яку валідацію, яка вимагає взаємодії з будь-яким **зовнішнім компонентом**, таким як база даних чи інший API, ви повинні замість цього використовувати **FastAPI Dependencies**. Ви дізнаєтесь про них пізніше.
|
||||
|
||||
Ці кастомні валідатори використовуються для речей, які можна перевірити лише з **тими даними**, що надані в запиті.
|
||||
|
||||
///
|
||||
|
||||
### Зрозумійте цей код
|
||||
|
||||
Головний момент – це використання **`AfterValidator` з функцією всередині `Annotated`**. Можете пропустити цю частину, якщо хочете. 🤸
|
||||
|
||||
---
|
||||
|
||||
Але якщо Вам цікаво розібратися в цьому конкретному прикладі коду і Вам ще не набридло, ось кілька додаткових деталей.
|
||||
|
||||
#### Рядок із `value.startswith()`
|
||||
|
||||
Звернули увагу? Рядок із `value.startswith()` може приймати кортеж, і тоді він перевірятиме кожне значення в кортежі:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
|
||||
|
||||
#### Випадковий елемент
|
||||
|
||||
За допомогою `data.items()` ми отримуємо <abbr title="Об'єкт, який можна перебирати в циклі, як-от список чи множину.">ітерабельний об'єкт</abbr> із кортежами, що містять ключ і значення для кожного елемента словника.
|
||||
|
||||
Ми перетворюємо цей ітерабельний об'єкт у звичайний `list` за допомогою `list(data.items())`.
|
||||
|
||||
Потім, використовуючи `random.choice()`, ми можемо отримати випадкове значення зі списку, тобто отримуємо кортеж із `(id, name)`. Це може бути щось на зразок `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
|
||||
|
||||
Далі ми **присвоюємо ці два значення** кортежу змінним `id` і `name`.
|
||||
|
||||
Тож, якщо користувач не вказав ID елемента, він все одно отримає випадкову рекомендацію.
|
||||
|
||||
...і все це реалізовано в **одному рядку коду**. 🤯 Хіба не прекрасний Python? 🐍
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
|
||||
|
||||
## Підсумок
|
||||
|
||||
Ви можете оголошувати додаткові валідації та метаінформацію для своїх параметрів.
|
||||
|
||||
Загальні валідації та метаінформація:
|
||||
|
||||
* `alias`
|
||||
* `title`
|
||||
* `description`
|
||||
* `deprecated`
|
||||
|
||||
Валідації, специфічні для рядків:
|
||||
|
||||
* `min_length`
|
||||
* `max_length`
|
||||
* `pattern`
|
||||
|
||||
Кастомні валідації за допомогою `AfterValidator`.
|
||||
|
||||
У цих прикладах Ви побачили, як оголошувати валідації для значень `str`.
|
||||
|
||||
Дивіться наступні розділи, щоб дізнатися, як оголошувати валідації для інших типів, наприклад чисел.
|
||||
Loading…
Reference in New Issue