Browse Source
๋ค์๊ณผ ๊ฐ์ด ๋ฒ์ญํ์์ต๋๋ค. - unwrap -> ์ธ๋ฉ(unwrap) #13061 ์ accept ์ฌ๋ถ์ ๋ฐ๋ผ ๋ฒ์ญ ๋ณ๊ฒฝ ์์ - unwraping -> ์ธ๋ํ(unwrapping) #13061 ์ accept ์ฌ๋ถ์ ๋ฐ๋ผ ๋ฒ์ญ ๋ณ๊ฒฝ ์์ - type annotation -> ํ์ ์ฃผ์(type annotation) - argument value -> ์ธ์ ๊ฐ(argument value)pull/13063/head
1 changed files with 223 additions and 0 deletions
@ -0,0 +1,223 @@ |
|||
# ์ถ๊ฐ ๋ชจ๋ธ |
|||
|
|||
์ง๋ ์์ ์ ์ด์ด์, ์ฐ๊ด๋ ๋ชจ๋ธ์ ์ฌ๋ฌ๊ฐ ๊ฐ๋ ๊ฒ์ ํํ ์ผ์
๋๋ค. |
|||
|
|||
ํนํ ์ ์ ๋ชจ๋ธ์ ๊ฒฝ์ฐ์ ๊ทธ๋ฌํ๋ฐ, ์๋ํ๋ฉด: |
|||
|
|||
* **์
๋ ฅ ๋ชจ๋ธ** ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฐ์ ธ์ผ ํฉ๋๋ค. |
|||
* **์ถ๋ ฅ ๋ชจ๋ธ** ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฐ์ง๋ฉด ์๋ฉ๋๋ค. |
|||
* **๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ** ์ ํด์์ฒ๋ฆฌ๋ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฐ์ง ๊ฒ์
๋๋ค. |
|||
|
|||
/// danger | ์ํ |
|||
|
|||
์ ๋ ์ ์ ์ ๋น๋ฐ๋ฒํธ๋ฅผ ํ๋ฌธ์ผ๋ก ์ ์ฅํ์ง ๋ง์ธ์. ํญ์ ์ดํ์ ๊ฒ์ฆ ๊ฐ๋ฅํ "์์ ํ ํด์(secure hash)"๋ก ์ ์ฅํ์ธ์. |
|||
|
|||
๋ง์ฝ ์ด๊ฒ ๋ฌด์์ธ์ง ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด, [security chapters](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.์์ ๋น๋ฐ๋ฒํธ ํด์์ ๋ํด ๋ฐฐ์ธ ์ ์์ต๋๋ค. |
|||
|
|||
/// |
|||
|
|||
## ๋ค์ค ๋ชจ๋ธ |
|||
|
|||
์๋๋ ๋น๋ฐ๋ฒํธ ํ๋์ ํด๋น ํ๋๊ฐ ์ฌ์ฉ๋๋ ์์น๋ฅผ ํฌํจํ์ฌ, ๊ฐ ๋ชจ๋ธ๋ค์ด ์ด๋ค ํํ๋ฅผ ๊ฐ์ง ์ ์๋์ง ์ ๋ฐ์ ์ธ ์์์
๋๋ค: |
|||
|
|||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *} |
|||
|
|||
|
|||
/// info | ์ ๋ณด |
|||
|
|||
Pydantic v1์์๋ ํด๋น ๋ฉ์๋๊ฐ `.dict()`๋ก ๋ถ๋ ธ์ผ๋ฉฐ, Pydantic v2์์๋ `.model_dump()`๋ก ์ด๋ฆ์ด ๋ณ๊ฒฝ๋์์ต๋๋ค. `.dict()`๋ ์ฌ์ ํ ์ง์๋์ง๋ง ๋ ์ด์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. |
|||
|
|||
์ฌ๊ธฐ์์ ์ฌ์ฉํ๋ ์์ ๋ Pydantic v1๊ณผ์ ํธํ์ฑ์ ์ํด `.dict()`๋ฅผ ์ฌ์ฉํ์ง๋ง, Pydantic v2๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ฉด `.model_dump()`๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. |
|||
|
|||
/// |
|||
|
|||
### `**user_in.dict()` ์ ๋ํ์ฌ |
|||
|
|||
#### Pydantic์ `.dict()` |
|||
|
|||
`user_in`์ Pydantic ๋ชจ๋ธ ํด๋์ค์ธ `UserIn`์
๋๋ค. |
|||
|
|||
Pydantic ๋ชจ๋ธ์ ๋ชจ๋ธ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ `dict`๋ฅผ ๋ฐํํ๋ `.dict()` ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค. |
|||
|
|||
๋ฐ๋ผ์, ๋ค์๊ณผ ๊ฐ์ด Pydantic ๊ฐ์ฒด `user_in`์ ์์ฑํ ์ ์์ต๋๋ค: |
|||
|
|||
```Python |
|||
user_in = UserIn(username="john", password="secret", email="[email protected]") |
|||
``` |
|||
|
|||
๊ทธ ๋ค์, ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํฉ๋๋ค: |
|||
|
|||
```Python |
|||
user_dict = user_in.dict() |
|||
``` |
|||
|
|||
์ด์ ๋ณ์ `user_dict`์ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ `dict`๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค(์ด๋ Pydantic ๋ชจ๋ธ ๊ฐ์ฒด๊ฐ ์๋ `dict`์
๋๋ค). |
|||
|
|||
๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ๋ฉด: |
|||
|
|||
```Python |
|||
print(user_dict) |
|||
``` |
|||
|
|||
Python์ `dict`๊ฐ ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค: |
|||
|
|||
```Python |
|||
{ |
|||
'username': 'john', |
|||
'password': 'secret', |
|||
'email': '[email protected]', |
|||
'full_name': None, |
|||
} |
|||
``` |
|||
|
|||
#### `dict` ์ธ๋ํ(Unwrapping) |
|||
|
|||
`user_dict`์ ๊ฐ์ `dict`๋ฅผ ํจ์(๋๋ ํด๋์ค)์ `**user_dict`๋ก ์ ๋ฌํ๋ฉด, Python์ ์ด๋ฅผ "์ธ๋ฉ(unwrap)"ํฉ๋๋ค. ์ด ๊ณผ์ ์์ `user_dict`์ ํค์ ๊ฐ์ ๊ฐ๊ฐ ํค-๊ฐ ์ธ์๋ก ์ง์ ์ ๋ฌํฉ๋๋ค. |
|||
|
|||
๋ฐ๋ผ์, ์์์ ์์ฑํ `user_dict`๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ฉด: |
|||
|
|||
```Python |
|||
UserInDB(**user_dict) |
|||
``` |
|||
|
|||
๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํฉ๋๋ค: |
|||
|
|||
```Python |
|||
UserInDB( |
|||
username="john", |
|||
password="secret", |
|||
email="[email protected]", |
|||
full_name=None, |
|||
) |
|||
``` |
|||
|
|||
ํน์ ๋ ์ ํํ ๋งํ์๋ฉด, `user_dict`๋ฅผ ์ง์ ์ฌ์ฉํ์ฌ, ๋ฏธ๋์ ์ด๋ค ๋ด์ฉ์ด ํฌํจ๋๋๋ผ๋: |
|||
|
|||
```Python |
|||
UserInDB( |
|||
username = user_dict["username"], |
|||
password = user_dict["password"], |
|||
email = user_dict["email"], |
|||
full_name = user_dict["full_name"], |
|||
) |
|||
``` |
|||
|
|||
#### ๋ค๋ฅธ Pydantic ๋ชจ๋ธ์ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ Pydantic ๋ชจ๋ธ ์์ฑ |
|||
|
|||
์์ ์์ ์์ `user_in.dict()`๋ก๋ถํฐ `user_dict`๋ฅผ ์์ฑํ ๊ฒ์ฒ๋ผ, ์๋ ์ฝ๋๋: |
|||
|
|||
```Python |
|||
user_dict = user_in.dict() |
|||
UserInDB(**user_dict) |
|||
``` |
|||
|
|||
๋ค์๊ณผ ๋์ผํฉ๋๋ค: |
|||
|
|||
```Python |
|||
UserInDB(**user_in.dict()) |
|||
``` |
|||
|
|||
...์๋ํ๋ฉด `user_in.dict()`๋ `dict`์ด๋ฉฐ, ์ด๋ฅผ `**`๋ก Python์ด "์ธ๋ฉ(unwrap)"ํ๋๋ก ํ์ฌ `UserInDB`์ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์
๋๋ค. |
|||
|
|||
๋ฐ๋ผ์, ๋ค๋ฅธ Pydantic ๋ชจ๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์๋ก์ด Pydantic ๋ชจ๋ธ์ ์์ฑํ ์ ์์ต๋๋ค. |
|||
|
|||
#### `dict` ์ธ๋ํ(Unwrapping)๊ณผ ์ถ๊ฐ ํค์๋ |
|||
|
|||
๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐ ํค์๋ ์ธ์ `hashed_password=hashed_password`๋ฅผ ํฌํจํ๋ฉด: |
|||
|
|||
```Python |
|||
UserInDB(**user_in.dict(), hashed_password=hashed_password) |
|||
``` |
|||
|
|||
๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํฉ๋๋ค: |
|||
|
|||
```Python |
|||
UserInDB( |
|||
username = user_dict["username"], |
|||
password = user_dict["password"], |
|||
email = user_dict["email"], |
|||
full_name = user_dict["full_name"], |
|||
hashed_password = hashed_password, |
|||
) |
|||
``` |
|||
|
|||
/// warning | ๊ฒฝ๊ณ |
|||
|
|||
์ถ๊ฐ์ ์ผ๋ก ์ ๊ณต๋ ํจ์ `fake_password_hasher`์ `fake_save_user`๋ ๋ฐ์ดํฐ ํ๋ฆ์ ์์ฐํ๊ธฐ ์ํ ์์ ์ผ ๋ฟ์ด๋ฉฐ, ์ค์ ๋ณด์์ ์ ๊ณตํ์ง ์์ต๋๋ค. |
|||
|
|||
/// |
|||
|
|||
## ์ค๋ณต ์ค์ด๊ธฐ |
|||
|
|||
์ฝ๋ ์ค๋ณต์ ์ค์ด๋ ๊ฒ์ **FastAPI**์ ํต์ฌ ์์ด๋์ด ์ค ํ๋์
๋๋ค. |
|||
|
|||
์ฝ๋ ์ค๋ณต์ ๋ฒ๊ทธ, ๋ณด์ ๋ฌธ์ , ์ฝ๋ ๋น๋๊ธฐํ ๋ฌธ์ (ํ ๊ณณ์ ์
๋ฐ์ดํธ๋์์ง๋ง ๋ค๋ฅธ ๊ณณ์ ์
๋ฐ์ดํธ๋์ง ์๋ ๋ฌธ์ ) ๋ฑ์ ๊ฐ๋ฅ์ฑ์ ์ฆ๊ฐ์ํต๋๋ค. |
|||
|
|||
๊ทธ๋ฆฌ๊ณ ์ด ๋ชจ๋ธ๋ค์ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ฉด์ ์์ฑ ์ด๋ฆ๊ณผ ํ์
์ ์ค๋ณตํ๊ณ ์์ต๋๋ค. |
|||
|
|||
๋ ๋์ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. |
|||
|
|||
`UserBase` ๋ชจ๋ธ์ ์ ์ธํ์ฌ ๋ค๋ฅธ ๋ชจ๋ธ๋ค์ ๊ธฐ๋ณธ(base)์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด ๋ชจ๋ธ์ ์์๋ฐ์ ์์ฑ๊ณผ ํ์
์ ์ธ(์ ํ ์ ์ธ, ๊ฒ์ฆ ๋ฑ)์ ์์ํ๋ ์๋ธํด๋์ค๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. |
|||
|
|||
๋ชจ๋ ๋ฐ์ดํฐ ๋ณํ, ๊ฒ์ฆ, ๋ฌธ์ํ ๋ฑ์ ์ ์์ ์ผ๋ก ์๋ํ ๊ฒ์
๋๋ค. |
|||
|
|||
์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ๋ชจ๋ธ ๊ฐ์ ์ฐจ์ด์ ๋ง ์ ์ธํ ์ ์์ต๋๋ค(ํ๋ฌธ `password`๊ฐ ์๋ ๊ฒฝ์ฐ, `hashed_password`๋ง ์๋ ๊ฒฝ์ฐ, ํน์ ๋น๋ฐ๋ฒํธ๊ฐ ์๋ ๊ฒฝ์ฐ): |
|||
|
|||
{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *} |
|||
|
|||
## `Union` ๋๋ `anyOf` |
|||
|
|||
๋ ๊ฐ์ง ์ด์์ ํ์
์ ํฌํจํ๋ `Union`์ผ๋ก ์๋ต์ ์ ์ธํ ์ ์์ต๋๋ค. ์ด๋ ์๋ต์ด ๊ทธ ์ค ํ๋์ ํ์
์ผ ์ ์์์ ์๋ฏธํฉ๋๋ค. |
|||
|
|||
OpenAPI์์๋ ์ด๋ฅผ `anyOf`๋ก ์ ์ํฉ๋๋ค. |
|||
|
|||
์ด๋ฅผ ์ํด ํ์ค Python ํ์
ํํธ์ธ <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>์ ์ฌ์ฉํ ์ ์์ต๋๋ค: |
|||
|
|||
/// note | ์ฐธ๊ณ |
|||
|
|||
<a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>์ ์ ์ํ ๋๋ ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ ๋จผ์ ํฌํจํ๊ณ , ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ ๊ทธ ๋ค์ ๋์ดํด์ผํฉ๋๋ค. ์๋ ์์ ์์๋ `Union[PlaneItem, CarItem]` ๋ฅผ ๋ณด๋ฉด, ๋ ๊ตฌ์ฒด์ ์ธ `PlaneItem`์ด `CarItem`๋ณด๋ค ์์ ์์นํฉ๋๋ค. |
|||
|
|||
/// |
|||
|
|||
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *} |
|||
|
|||
|
|||
### Python 3.10์์ `Union` |
|||
|
|||
์์ ์์ ์์๋ `response_model` ์ธ์ ๊ฐ์ผ๋ก `Union[PlaneItem, CarItem]`์ ์ ๋ฌํฉ๋๋ค. |
|||
|
|||
์ด ๊ฒฝ์ฐ, ์ด๋ฅผ **ํ์
์ฃผ์(type annotation)** ์ด ์๋ **์ธ์ ๊ฐ(argument value)** ์ผ๋ก ์ ๋ฌํ๊ณ ์๊ธฐ ๋๋ฌธ์ Python 3.10์์๋ `Union`์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. |
|||
|
|||
๋ง์ฝ ํ์
์ฃผ์์ ์ฌ์ฉํ๋ค๋ฉด, ๋ค์๊ณผ ๊ฐ์ด ์์ง ๋ง๋(|)๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค: |
|||
|
|||
```Python |
|||
some_variable: PlaneItem | CarItem |
|||
``` |
|||
|
|||
ํ์ง๋ง ์ด๋ฅผ `response_model=PlaneItem | CarItem`๊ณผ ๊ฐ์ด ํ ๋นํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ Python์ด ์ด๋ฅผ ํ์
์ฃผ์์ผ๋ก ํด์ํ์ง ์๊ณ , `PlaneItem`๊ณผ `CarItem` ์ฌ์ด์ **์๋ชป๋ ์ฐ์ฐ(invalid operation)**์ ์๋ํ๊ธฐ ๋๋ฌธ์
๋๋ค |
|||
|
|||
## ๋ชจ๋ธ ๋ฆฌ์คํธ |
|||
|
|||
๋ง์ฐฌ๊ฐ์ง๋ก, ๊ฐ์ฒด ๋ฆฌ์คํธ ํํ์ ์๋ต์ ์ ์ธํ ์๋ ์์ต๋๋ค. |
|||
|
|||
์ด๋ฅผ ์ํด ํ์ค Python์ `typing.List`๋ฅผ ์ฌ์ฉํ์ธ์(๋๋ Python 3.9 ์ด์์์๋ ๋จ์ํ `list`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค): |
|||
|
|||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *} |
|||
|
|||
|
|||
## ์์์ `dict` ์๋ต |
|||
|
|||
Pydantic ๋ชจ๋ธ์ ์ฌ์ฉํ์ง ์๊ณ , ํค์ ๊ฐ์ ํ์
๋ง ์ ์ธํ์ฌ ํ๋ฒํ ์์์ `dict`๋ก ์๋ต์ ์ ์ธํ ์๋ ์์ต๋๋ค. |
|||
|
|||
์ด๋ Pydantic ๋ชจ๋ธ์ ํ์ํ ์ ํจํ ํ๋/์์ฑ ์ด๋ฆ์ ์ฌ์ ์ ์ ์ ์๋ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค. |
|||
|
|||
์ด ๊ฒฝ์ฐ, `typing.Dict`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค(๋๋ Python 3.9 ์ด์์์๋ ๋จ์ํ `dict`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค): |
|||
|
|||
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *} |
|||
|
|||
|
|||
## ์์ฝ |
|||
|
|||
์ฌ๋ฌ Pydantic ๋ชจ๋ธ์ ์ฌ์ฉํ๊ณ , ๊ฐ ๊ฒฝ์ฐ์ ๋ง๊ฒ ์์ ๋กญ๊ฒ ์์ํ์ธ์. |
|||
|
|||
์ํฐํฐ๊ฐ ์๋ก ๋ค๋ฅธ "์ํ"๋ฅผ ๊ฐ์ ธ์ผ ํ๋ ๊ฒฝ์ฐ, ์ํฐํฐ๋น ๋จ์ผ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ์ฌ์ฉํ ํ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์ "์ํฐํฐ"๊ฐ `password`, `password_hash`, ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์๋ ์ํ๋ฅผ ํฌํจํ ์ ์๋ ๊ฒฝ์ฐ์ฒ๋ผ ๋ง์
๋๋ค. |
Loadingโฆ
Reference in new issue