]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Add Korean translation for `docs/ko/docs/tutorial/extra-models.md` (#13063)
authortimothy <53824764+timothy-jeong@users.noreply.github.com>
Fri, 30 May 2025 13:38:33 +0000 (22:38 +0900)
committerGitHub <noreply@github.com>
Fri, 30 May 2025 13:38:33 +0000 (15:38 +0200)
docs/ko/docs/tutorial/extra-models.md [new file with mode: 0644]

diff --git a/docs/ko/docs/tutorial/extra-models.md b/docs/ko/docs/tutorial/extra-models.md
new file mode 100644 (file)
index 0000000..8e45590
--- /dev/null
@@ -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="john.doe@example.com")
+```
+
+κ·Έ λ‹€μŒ, λ‹€μŒκ³Ό κ°™μ΄ ν˜ΈμΆœν•©λ‹ˆλ‹€:
+
+```Python
+user_dict = user_in.dict()
+```
+
+이제 λ³€μˆ˜ `user_dict`에 λ°μ΄ν„°κ°€ ν¬ν•¨λœ `dict`λ₯Ό κ°€μ§€κ²Œ λ©λ‹ˆλ‹€(μ΄λŠ” Pydantic λͺ¨λΈ κ°μ²΄κ°€ μ•„λ‹Œ `dict`μž…λ‹ˆλ‹€).
+
+그리고 λ‹€μŒκ³Ό κ°™μ΄ ν˜ΈμΆœν•˜λ©΄:
+
+```Python
+print(user_dict)
+```
+
+Python의 `dict`κ°€ λ‹€μŒκ³Ό κ°™μ΄ μΆœλ ₯λ©λ‹ˆλ‹€:
+
+```Python
+{
+    'username': 'john',
+    'password': 'secret',
+    'email': 'john.doe@example.com',
+    'full_name': None,
+}
+```
+
+#### `dict` μ–ΈνŒ¨ν‚Ή(Unpacking)
+
+`user_dict`와 κ°™μ€ `dict`λ₯Ό ν•¨μˆ˜(λ˜λŠ” ν΄λž˜μŠ€)에 `**user_dict`둜 μ „λ‹¬ν•˜λ©΄, Python은 μ΄λ₯Ό "μ–ΈνŒ©(unpack)"ν•©λ‹ˆλ‹€. μ΄ κ³Όμ •μ—μ„œ `user_dict`의 ν‚€μ™€ κ°’을 κ°κ° ν‚€-κ°’ μΈμžλ‘œ μ§μ ‘ μ „λ‹¬ν•©λ‹ˆλ‹€.
+
+λ”°λΌμ„œ, μœ„μ—μ„œ μƒμ„±ν•œ `user_dict`λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€μŒκ³Ό κ°™μ΄ μž‘μ„±ν•˜λ©΄:
+
+```Python
+UserInDB(**user_dict)
+```
+
+λ‹€μŒκ³Ό κ°™μ€ κ²°κ³Όλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€:
+
+```Python
+UserInDB(
+    username="john",
+    password="secret",
+    email="john.doe@example.com",
+    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 λͺ¨λΈ μƒμ„±
+
+μœ„μ˜ μ˜ˆμ œμ—μ„œ `user_in.dict()`λ‘œλΆ€ν„° `user_dict`λ₯Ό μƒμ„±ν•œ κ²ƒμ²˜λŸΌ, μ•„λž˜ μ½”λ“œλŠ”:
+
+```Python
+user_dict = user_in.dict()
+UserInDB(**user_dict)
+```
+
+λ‹€μŒκ³Ό λ™μΌν•©λ‹ˆλ‹€:
+
+```Python
+UserInDB(**user_in.dict())
+```
+
+...μ™œλƒν•˜λ©΄ `user_in.dict()`λŠ” `dict`이며, μ΄λ₯Ό `**`둜 Python이 "μ–ΈνŒ©(unpack)"ν•˜λ„λ‘ ν•˜μ—¬ `UserInDB`에 μ „λ‹¬ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
+
+λ”°λΌμ„œ, λ‹€λ₯Έ Pydantic λͺ¨λΈμ˜ λ°μ΄ν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒˆλ‘œμš΄ Pydantic λͺ¨λΈμ„ μƒμ„±ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+#### `dict` μ–ΈνŒ¨ν‚Ή(Unpacking)κ³Ό μΆ”κ°€ ν‚€μ›Œλ“œ
+
+그리고 λ‹€μŒκ³Ό κ°™μ΄ μΆ”κ°€ ν‚€μ›Œλ“œ μΈμž `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`, λ˜λŠ” λΉ„λ°€λ²ˆν˜Έκ°€ μ—†λŠ” μƒνƒœλ₯Ό ν¬ν•¨ν•  μˆ˜ μžˆλŠ” κ²½μš°μ²˜λŸΌ λ§μž…λ‹ˆλ‹€.