๐ Django 'NoReverseMatch' ์ค๋ฅ ๋ง์คํฐ ์ฒญ์ฌ์ง
๐ก ์ํฉ ํด๋
- ํ์ฌ ์ํ: ์น์ฌ์ดํธ์ ํน์ ํ์ด์ง(
/webtools
)์ ์ ์ํ๋ฉด "์๋ฒ ๋ด๋ถ ์ค๋ฅ (500)" ๋ฉ์์ง๊ฐ ๋จ๋ฉด์ ํ์ด์ง๊ฐ ์ด๋ฆฌ์ง ์์ต๋๋ค. ๊ฐ๋ฐ ์๋ฒ ๋ก๊ทธ์๋ยNoReverseMatch
๋ผ๋ ์ด๋ฆ์ ์ค๋ฅ๊ฐ ๊ธฐ๋ก๋์ด ์์ต๋๋ค. - ํต์ฌ ์์ :
- ์น ํ์ด์ง๋ฅผ ๋ง๋ค๋ ค๊ณ ์๋ํ์ง๋ง, ํน์ ๋งํฌ(URL)๋ฅผ ์์ฑํ๋ ๋ฐ ์คํจํ์ต๋๋ค.
- ์์คํ
์ย
'clova'
๋ผ๋ ์ด๋ฆํ๊ฐ ๋ถ์ ๊ธธ(URL ์ฃผ์)์ ์ฐพ์ผ๋ผ๋ ์ง์๋ฅผ ๋ฐ์์ง๋ง, ๊ทธ๋ฐ ์ด๋ฆํ๋ฅผ ๊ฐ์ง ๊ธธ์ด ์ด๋์๋ ๋ฑ๋ก๋์ด ์์ง ์์ต๋๋ค. - ์ด ๋๋ฌธ์ ํ์ด์ง ์ ์ฒด๋ฅผ ์์ฑํ์ง ๋ชปํ๊ณ ์ค๋ฅ๋ฅผ ํ์ํ๊ณ ์์ต๋๋ค.
- ์์ vs ํ์ค: ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ์ด ํ์ด์ง๊ฐ ๋ฌธ์ ์์ด ์ ๋ณด์๋๋ฐ, ์ค์ ์ด์ ์๋ฒ์์๋ ๊ฐ์๊ธฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ถ๋ช ํ ๋งํฌ๊ฐ ์ ์ฐ๊ฒฐ๋ ๊ฒ์ด๋ผ๊ณ ์์ํ์ง๋ง, ์ค์ ๋ก๋ ์์คํ ์ด ํด๋น ๋งํฌ์ ์ฃผ์๋ฅผ ์ฐพ์ง ๋ชปํ๊ณ ์์ต๋๋ค.
- ์ํฅ ๋ฒ์: ์ฌ์ฉ์๋ย
/webtools
ย ํ์ด์ง์ ์ ๊ทผํ ์ ์์ผ๋ฉฐ, ํด๋น ํ์ด์ง์ ํฌํจ๋ ๊ธฐ๋ฅ(์น ๋๊ตฌ ๋ชฉ๋ก)์ ์ ํ ์ด์ฉํ ์ ์์ต๋๋ค. ์น์ฌ์ดํธ์ ์ค์ํ ๊ธฐ๋ฅ ์ผ๋ถ๊ฐ ๋ง๋น๋ ์ํ์ ๋๋ค.
๐ ์์ธ ํฌ์
- ๊ทผ๋ณธ ์์ธ: ์น ํ์ด์ง(HTML ํ
ํ๋ฆฟ) ์ฝ๋ ์ด๋๊ฐ์์ย
{% url 'clova' %}
๋ผ๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ 'clova'๋ผ๋ ๋ณ๋ช ์ ๊ฐ์ง URL ์ฃผ์๋ฅผ ๋ง๋ค์ด๋ฌ๋ผ๊ณ ์์ฒญํ์ต๋๋ค. ํ์ง๋ง ์ค์ URL ๊ฒฝ๋ก๋ฅผ ์ ์ํ๋ ํ์ผ(urls.py
)์๋ 'clova'๋ผ๋ ๋ณ๋ช ์ผ๋ก ๋ฑ๋ก๋ ์ฃผ์๊ฐ ์์ต๋๋ค. ์ฆ,ย ์๋ ๋ณ๋ช ์ผ๋ก ์ฃผ์๋ฅผ ์ฐพ์๋ฌ๋ผ๊ณ ์์ฒญํ ๊ฒ์ด ๋ฌธ์ ์ ๋๋ค. - ์ฐ๊ฒฐ ๊ณ ๋ฆฌ:
- ์ฌ์ฉ์๊ฐย
/webtools
ย ํ์ด์ง๋ฅผ ์์ฒญํฉ๋๋ค. - ์๋ฒ(Django)๋ ํด๋น ํ์ด์ง๋ฅผ ๋ง๋ค๊ธฐ ์ํดย
webtools/tool_list.html
ย ํ ํ๋ฆฟ ํ์ผ์ ์ฝ์ต๋๋ค. - ํ
ํ๋ฆฟ ํ์ผ ์์๋ ์น ๋๊ตฌ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ ๋ถ๋ถ์ด ์๊ณ , ๊ฐ ๋๊ตฌ๋ก ๊ฐ๋ ๋งํฌ๋ฅผย
{% url '๋ณ๋ช ' %}
ย ์ฝ๋๋ฅผ ์ด์ฉํด ๋์ ์ผ๋ก ์์ฑํฉ๋๋ค. - 'AI ์ฑ๋ด' ๋๊ตฌ ์ฐจ๋ก์์, ์์คํ
์ย
webtools.json
ย ํ์ผ์ ์ ํยurl_name
ย ๊ฐ('clova')์ ๊ฐ์ ธ์ย{% url 'clova' %}
๋ฅผ ์คํํฉ๋๋ค. - Django์ URL ์์คํ ์ ๋ฑ๋ก๋ ๋ชจ๋ URL ํจํด์ ๋ค์ ธ๋ณด์ง๋ง 'clova'๋ผ๋ ๋ณ๋ช ์ ๊ฐ์ง ํจํด์ ์ฐพ์ง ๋ชปํฉ๋๋ค.
- ์ฃผ์๋ฅผ ์ฐพ์ง ๋ชปํ์ผ๋ฏ๋กย
NoReverseMatch
ย ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๊ณ ํ์ด์ง ๋ ๋๋ง์ ์ค๋จํฉ๋๋ค. - ์ฌ์ฉ์์๊ฒ๋ 500 ์๋ฒ ์ค๋ฅ๊ฐ ํ์๋ฉ๋๋ค.
- ์ผ์ ๋น์ :
- ์๋ชป๋ ๋ณ๋ช ๋ถ๋ฅด๊ธฐ: ์น๊ตฌ์๊ฒ "์ผ, 'ํด๋ก๋ฐ' ์ด๋ ๊ฐ์ด?"๋ผ๊ณ ๋ฌผ์๋๋ฐ, ์๋ฌด๋ ๊ทธ ์น๊ตฌ๋ฅผ 'ํด๋ก๋ฐ'๋ผ๊ณ ๋ถ๋ฅด์ง ์๊ณ ๊ณต์ ๋ณ๋ช ์ '์ฑ๋ด'์ธ ์ํฉ๊ณผ ๊ฐ์ต๋๋ค. ์์คํ ์ 'ํด๋ก๋ฐ'๊ฐ ๋๊ตฌ์ธ์ง ๋ชจ๋ฅด๋ ๊ฒ์ ๋๋ค.
- ์ค๋๋ ์ฃผ์๋ก ์ฌ์ฉ: ์ด์ฌ ๊ฐ ์น๊ตฌ์ ์๋ ์ฃผ์๋ก ํธ์ง๋ฅผ ๋ณด๋ด๋ ค๊ณ ํ๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค. ์ฃผ์๋ก์๋ 'clova'๋ผ๋ ์๋ ์ฃผ์๋ง ์ ํ์๊ณ , ์ค์ ์ฐํธ ์์คํ (URL ์์คํ )์๋ ๊ทธ ์ฃผ์๊ฐ ๋ ์ด์ ์ ํจํ์ง ์์ ๊ฒ์ ๋๋ค.
- ๋ฉ๋ดํ์ ์๋ ๋ฉ๋ด ์ฃผ๋ฌธ: ์๋น ๋ฉ๋ดํ์ 'ํด๋ก๋ฐ ์ ์'์ด ์๋๋ฐ, ์จ์ดํฐ์๊ฒ 'ํด๋ก๋ฐ ์ ์'์ ๋ฌ๋ผ๊ณ ์์ฒญํ๋ ์ํฉ์ ๋๋ค. ์ฃผ๋ฐฉ(URL ์์คํ )์์๋ ๊ทธ๋ฐ ๋ฉ๋ด๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
- ์จ๊ฒจ์ง ์์:
- ๋ค์์คํ์ด์ค(Namespace): Django์์๋ ์ฑ๋ณ๋ก URL ๋ณ๋ช
์ถฉ๋์ ๋ง๊ธฐ ์ํด '์์'์ ํ์ํ๋ ๋ค์์คํ์ด์ค(์:ย
'CLOVA:chat_interface'
)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ค๋ฅ๋ ๋ค์์คํ์ด์ค ์์ด ๋ณ๋ช ๋ง ์ฌ์ฉํ๊ฑฐ๋, ์๋ชป๋ ๋ค์์คํ์ด์ค๋ฅผ ์ฌ์ฉํ์ ๋ ์์ฃผ ๋ฐ์ํฉ๋๋ค. - ์ค์ ํ์ผ ๋ถ๋ฆฌ: ๊ฐ๋ฐ ํ๊ฒฝ๊ณผ ์ด์ ํ๊ฒฝ์ ์ค์ (
settings/development.py
,ยsettings/production.py
)์ด ๋ค๋ฅผ ์ ์์ต๋๋ค. URL ์ค์ ์์ฒด๋ ๊ฐ๋๋ผ๋, URL ์์ฑ์ ์ํด ์ฐธ์กฐํ๋ ๋ฐ์ดํฐ(์:ยwebtools.json
)๊ฐ ํ๊ฒฝ๋ณ๋ก ๋ค๋ฅด๊ฑฐ๋ ๋๊ธฐํ๋์ง ์์์ ์ ์์ต๋๋ค. (์ด๋ฒ ๊ฒฝ์ฐ๋ยwebtools.json
์ยurl_name
์ด ์๋ชป๋ ๊ฒ์ด ์์ธ์ด์์ต๋๋ค.) - ํ
ํ๋ฆฟ ์์/ํฌํจ: ์ค๋ฅ๊ฐ ๋ฐ์ํย
{% url 'clova' %}
ย ์ฝ๋๊ฐ ์ง์ ์ ์ผ๋กยwebtools/tool_list.html
์ ์์ ์๋ ์์ต๋๋ค. ์ด ํ ํ๋ฆฟ์ด ์์๋ฐ๋ ๋ถ๋ชจ ํ ํ๋ฆฟ(base.html
ย ๋ฑ)์ด๋ ํฌํจํ๋ ๋ค๋ฅธ ์์ ํ ํ๋ฆฟ ์กฐ๊ฐ ์์ ์์ ์ ์์ต๋๋ค. (์ด๋ฒ ๊ฒฝ์ฐ๋ยwebtools.json
์ ์ฐธ์กฐํ๋ยtool_list.html
์์ ๋ฐ์ํ์ต๋๋ค.)
๐ ๏ธ ํด๊ฒฐ ์ค๊ณ๋
- ์ค๋ฅ ์ง์ ํ์ธ (ํ ํ๋ฆฟ ๋๋ ์ฐธ์กฐ ๋ฐ์ดํฐ)
- ํต์ฌ ํ๋:ย
NoReverseMatch
ย ์ค๋ฅ ๋ฉ์์ง์์ ์ด๋ค URL ์ด๋ฆ('clova')์ ์ฐพ์ง ๋ชปํ๋์ง ํ์ธํ๊ณ , ์ด ์ด๋ฆ์ ์ฌ์ฉํ๋ ๊ณณ์ ์ฐพ์ต๋๋ค. - ์คํ ๊ฐ์ด๋:
- ์๋ฒ ๋ก๊ทธ์์ย
NoReverseMatch: Reverse for 'clova' not found...
ย ๋ฉ์์ง๋ฅผ ํ์ธํฉ๋๋ค. ์ฌ๊ธฐ์ 'clova'๊ฐ ๋ฌธ์ ์ ์ด๋ฆ์ ๋๋ค. webtools/tool_list.html
ย ํ ํ๋ฆฟ ํ์ผ์ ์ฝ๋๋ค.- ํ
ํ๋ฆฟ ์ฝ๋์์ย
{% url ... %}
ย ํ๊ทธ๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ถ์ ์ฐพ์ต๋๋ค. - ํนํย
webtools
ย ๋ณ์๋ฅผ ๋ฐ๋ณตํ๋ฉฐ ๊ฐยtool
์ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ถ์ ์ฃผ๋ชฉํฉ๋๋ค.ย{% url tool.url_name %}
ย ๋๋ ์ ์ฌํ ์ฝ๋๊ฐ ์๋์ง ํ์ธํฉ๋๋ค. - ๋ง์ฝ ์ ์ฝ๋๊ฐ ์๋ค๋ฉด,ย
tool.url_name
ย ๊ฐ์ด 'clova'๊ฐ ๋๋ ๊ฒฝ์ฐ๋ฅผ ์ฐพ์ต๋๋ค. ์ด๋ยwebtools.json
ย ํ์ผ์์ 'AI ์ฑ๋ด' ๋๊ตฌ์ยurl_name
์ผ๋ก ์ค์ ๋์ด ์์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
- ์ฑ๊ณต ์งํ: ํ
ํ๋ฆฟ ์ฝ๋ ๋๋ย
webtools.json
ย ํ์ผ์์ 'clova'๋ผ๋ ์ด๋ฆ์ ์ฌ์ฉํ๋ ์ ํํ ์์น๋ฅผ ์ฐพ์๋ ๋๋ค. - ์์/์ฝ๋ย (ํด๋น์ -ย
webtools.json
ย ์์ ):
// ๋ณ๊ฒฝ ์ (webtools/config/webtools.json ๋ด๋ถ) { "title": "AI ์ฑ๋ด", "description": "์ธ๊ณต์ง๋ฅ๊ณผ ๋ํํ๊ธฐ", "url_name": "clova", // <<< ๋ฌธ์ ์ ์์ธ "icon": "fas fa-robot", "category": "webtools", // ๋๋ ai-tools "order": 15, "is_active": true } // ๋ณ๊ฒฝ ํ { "title": "AI ์ฑ๋ด", "description": "์ธ๊ณต์ง๋ฅ๊ณผ ๋ํํ๊ธฐ", "url_name": "CLOVA:chat_interface", // <<< ์ฌ๋ฐ๋ฅธ ์ด๋ฆ์ผ๋ก ์์ "icon": "fas fa-robot", "category": "webtools", // ๋๋ ai-tools "order": 15, "is_active": true } // ํต์ฌ ๋ณํ ์ค๋ช // AI ์ฑ๋ด ๋๊ตฌ์ URL ๋ณ๋ช ์ Django URL ์์คํ ์ด ์ธ์ํ ์ ์๋ // ์ ํํ ์ด๋ฆ('CLOVA' ์ฑ ๋ค์์คํ์ด์ค์ 'chat_interface' ๋ณ๋ช )์ผ๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
- ์ฃผ์์ฌํญ:ย
webtools.json
์ ์์ ํ๋ ๋์ ํ ํ๋ฆฟ(webtools/tool_list.html
)์ ์์ ํ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ดย{% url tool.url_name %}
ย ๋์ ยhref="{{ tool.url }}"
ย ์ฒ๋ผ ๋ฏธ๋ฆฌ ์์ฑ๋ URL ๊ฒฝ๋ก๋ฅผ ์ง์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ์ง๋ง JSON ํ์ผ์์ ์ ํํยurl_name
์ ์ ๊ณตํ๋ ๊ฒ์ด ๋ ๊ถ์ฅ๋ฉ๋๋ค.
- ์ฌ๋ฐ๋ฅธ URL ์ด๋ฆ ํ์ธ
- ํต์ฌ ํ๋: 'clova' ๋์ ์ฌ์ฉํด์ผ ํ ์ ํํ URL ๋ณ๋ช ๊ณผ ๋ค์์คํ์ด์ค๋ฅผ ํ์ธํฉ๋๋ค.
- ์คํ ๊ฐ์ด๋:
- CLOVA AI ์ฑ๋ด ๊ธฐ๋ฅ์ ๋ด๋นํ๋ Django ์ฑ ๋๋ ํ ๋ฆฌ (
django/CLOVA/
)๋ก ์ด๋ํฉ๋๋ค. urls.py
ย ํ์ผ์ ์ฝ๋๋ค.- ํ์ผ ์๋จ์ย
app_name = 'CLOVA'
ย ์ ๊ฐ์ด ๋ค์์คํ์ด์ค๊ฐ ์ ์๋์ด ์๋์ง ํ์ธํฉ๋๋ค. (๋์๋ฌธ์ ๊ตฌ๋ถ ์ค์!) urlpatterns
ย ๋ฆฌ์คํธ์์ ์ฑ๋ด ๋ทฐ์ ์ฐ๊ฒฐ๋ยpath()
ย ํจ์๋ฅผ ์ฐพ์ต๋๋ค.- ํด๋นย
path()
ย ํจ์์ยname='...'
ย ๋ถ๋ถ์ ํ์ธํฉ๋๋ค. (์:ยname='chat_interface'
) - ์ฌ๋ฐ๋ฅธ ์ ์ฒด ์ด๋ฆ์ย
'๋ค์์คํ์ด์ค:์ด๋ฆ'
ย ํ์์ ๋๋ค. (์:ย'CLOVA:chat_interface'
)
- ์ฑ๊ณต ์งํ: CLOVA ์ฑ๋ด URL์ ์ ํํ ๋ค์์คํ์ด์ค์ ๋ณ๋ช ์ ํ์ธํฉ๋๋ค.
- ์์/์ฝ๋ย (ํด๋น์ -ย
CLOVA/urls.py
ย ํ์ธ):
# django/CLOVA/urls.py from django.urls import path from . import views app_name = 'CLOVA' # <<< ๋ค์์คํ์ด์ค ํ์ธ ('CLOVA') urlpatterns = [ path('', views.clova_chat, name='chat_interface'), # <<< ๋ณ๋ช ํ์ธ ('chat_interface') ] # ๋ฐ๋ผ์ ์ฌ๋ฐ๋ฅธ ์ด๋ฆ์ 'CLOVA:chat_interface' ์ ๋๋ค.
- ์ฃผ์์ฌํญ: ๋ค์์คํ์ด์ค๋ ๋์๋ฌธ์๋ฅผ ์ ํํ ๊ตฌ๋ถํด์ผ ํฉ๋๋ค. 'clova'์ 'CLOVA'๋ ๋ค๋ฆ ๋๋ค.
- ์ค์ ์ ์ฉ ๋ฐ ํ ์คํธ
- ํต์ฌ ํ๋: ์์ ๋ ๋ด์ฉ์ ์ ์ฅํ๊ณ , ๋ณ๊ฒฝ์ฌํญ์ด ์ ์ฉ๋๋๋ก ์๋ฒ๋ฅผ ์ฌ์์ํ ํ, ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์๋์ง ํ์ธํฉ๋๋ค.
- ์คํ ๊ฐ์ด๋:
webtools.json
ย ํ์ผ์ ์์ ํ ๊ฒฝ์ฐ, ํ์ผ์ ์ ์ฅํฉ๋๋ค.- ์ด์ ํ๊ฒฝ์ Django ์ปจํ
์ด๋๋ฅผ ์ฌ์์ํฉ๋๋ค. (์ด์ ๊ฒฝํ์ย
docker-compose down
ย ํยdocker-compose up
์ด ์บ์ ๋ฌธ์ ๊น์ง ํด๊ฒฐํ๋ ๋ฐ ๋ ํ์คํ ์ ์์ต๋๋ค.) - ๋ธ๋ผ์ฐ์ ์์ย
/webtools
ย ํ์ด์ง์ ๋ค์ ์ ์ํ์ฌ 500 ์ค๋ฅ ์์ด ํ์ด์ง๊ฐ ์ ์์ ์ผ๋ก ๋ก๋๋๋์ง ํ์ธํฉ๋๋ค. - ํ์ด์ง ๋ด์ 'AI ์ฑ๋ด' ๋งํฌ๊ฐ ์ฌ๋ฐ๋ฅธ ์ฃผ์(
/clova/
)๋ก ์ฐ๊ฒฐ๋๋์ง ํ์ธํฉ๋๋ค.
- ์ฑ๊ณต ์งํ:ย
/webtools
ย ํ์ด์ง๊ฐ ์ค๋ฅ ์์ด ์ด๋ฆฌ๊ณ ๋ชจ๋ ๋งํฌ๊ฐ ์ ์์ ์ผ๋ก ์๋ํฉ๋๋ค. - ์ฃผ์์ฌํญ: ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ํ์๋ ํญ์ ์บ์๋ฅผ ๋น์ฐ๊ฑฐ๋ ์๋ฒ๋ฅผ ์์ ํ ์ฌ์์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํนํ ์ด์ ํ๊ฒฝ์์๋ ์์์น ๋ชปํ ์บ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๐ง ํต์ฌ ๊ฐ๋ ํด๋ถ
- URL ์ด๋ฆ(name) & ๋ค์์คํ์ด์ค(namespace): ์ผ์์ ์ฌ์ ์
- 5์ด์๊ฒ ์ค๋ช ํ๋ค๋ฉด: ์น์ฌ์ดํธ ํ์ด์ง๋ง๋ค ๋ณ๋ช ์ ์ง์ด์ฃผ๋ ๊ฑฐ์ผ. '์ฑ๋ด๋ฐฉ'์ฒ๋ผ. ๊ทธ๋ฐ๋ฐ ๋ค๋ฅธ ์ฑ์๋ '์ฑ๋ด๋ฐฉ'์ด ์์ ์ ์์ผ๋, ์์ 'ํด๋ก๋ฐ๋ค_์ฑ๋ด๋ฐฉ'์ฒ๋ผ ์์(๋ค์์คํ์ด์ค)์ ๋ถ์ฌ์ ํท๊ฐ๋ฆฌ์ง ์๊ฒ ํ๋ ๊ฑฐ์ง.
- ์ค์ํ ์์: ํ์ฌ์์ ๊ฐ์ ์ด๋ฆ(๊น์ฒ ์)์ ๊ฐ์ง ์ฌ๋์ด ์ฌ๋ฌ ๋ช ์์ ๋, "์์ ๋ถ ๊น์ฒ ์"์ฒ๋ผ ๋ถ์(๋ค์์คํ์ด์ค)๋ฅผ ๋ถ์ฌ ๊ตฌ๋ถํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. 'CLOVA:chat_interface'๋ 'CLOVA ์ฑ์ ์์๋ chat_interface๋ผ๋ ๋ณ๋ช ์ ๊ฐ์ง URL'์ด๋ผ๋ ๋ป์ ๋๋ค.
- ์จ๊ฒจ์ง ์ค์์ฑ: URL ์ฃผ์(/clova/)๋ฅผ ์ฝ๋์ ์ง์ ์ฐ๋ ๋์ ๋ณ๋ช
์ ์ฐ๋ฉด, ๋์ค์ ์ฃผ์๋ฅผ ๋ฐ๊ฟ์ผ ํ ๋ URL ์ค์ ํ์ผ(
urls.py
)๋ง ๊ณ ์น๋ฉด ๋ฉ๋๋ค. ๋ณ๋ช ์ ์ฌ์ฉํ ๋ชจ๋ ๋งํฌ๊ฐ ์๋์ผ๋ก ์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋์ด ์ ์ง๋ณด์๊ฐ ๋งค์ฐ ํธ๋ฆฌํด์ง๋๋ค. (ํ๋์ฝ๋ฉ ๋ฐฉ์ง) - ์คํด์ ์ง์ค:
- ์คํด: URL ์ด๋ฆ์ ๋์ถฉ ์ง์ด๋ ๋๋ค.
- ์ง์ค: ๋ช ํํ๊ณ ์ผ๊ด๋ ๊ท์น์ผ๋ก ์ด๋ฆ์ ์ง์ด์ผ ํ๋ฉฐ, ํนํ ๋ค์์คํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ์ฑ๊ณผ์ ์ถฉ๋์ ํผํด์ผ ํฉ๋๋ค.
- ์คํด: ๋ค์์คํ์ด์ค๋ ๋ณต์กํ๋ ์ ์จ๋ ๋๋ค.
- ์ง์ค: ์ฑ์ด ๋ง์์ง๋ฉด ๋ค์์คํ์ด์ค ์์ด๋ ์ด๋ฆ ์ถฉ๋๋ก ํฐ ํผ๋์ด ๋ฐ์ํ๋ฏ๋ก ํ์์ ์ ๋๋ค.
- {% url %}ย ํ ํ๋ฆฟ ํ๊ทธ: ์ผ์์ ์ฌ์ ์
- 5์ด์๊ฒ ์ค๋ช
ํ๋ค๋ฉด: ์น ํ์ด์ง์ ๋ฒํผ์ด๋ ๋งํฌ๋ฅผ ๋ง๋ค ๋, "์ด ๋ฒํผ ๋๋ฅด๋ฉด 'ํด๋ก๋ฐ๋ค_์ฑ๋ด๋ฐฉ'์ผ๋ก ๊ฐ!"๋ผ๊ณ ์ํค๋ ๋ง๋ฒ ์ฃผ๋ฌธ์ด์ผ. ๊ทธ๋ผ Django๊ฐ ์์์ ์ง์ง ์ฃผ์(
/clova/
)๋ฅผ ์ฐพ์์ ๋งํฌ๋ฅผ ๋ง๋ค์ด์ค. - ์ค์ํ ์์: ์ ํ๋ฒํธ๋ถ์ ์น๊ตฌ ์ด๋ฆ('์ฑ๋ด')๋ง ์ ์ฅํด๋๊ณ , ์ ํ๋ฅผ ๊ฑธ ๋ ์ด๋ฆ๋ง ๋๋ฅด๋ฉด ์ ํ๊ธฐ๊ฐ ์์์ ์ค์ ๋ฒํธ('010-1234-5678')๋ฅผ ์ฐพ์ ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค.
- ์จ๊ฒจ์ง ์ค์์ฑ: URL ์ฃผ์๊ฐ ๋ณ๊ฒฝ๋์ด๋ ํ
ํ๋ฆฟ ํ์ผ์ ์์ ํ ํ์๊ฐ ์์ต๋๋ค.ย
urls.py
์์ ๋ณ๋ช ์ ์ฐ๊ฒฐ๋ ์ฃผ์๋ง ๋ฐ๊พธ๋ฉดย{% url %}
ย ํ๊ทธ๊ฐ ํญ์ ์ต์ ์ฃผ์๋ฅผ ์์ฑํด์ฃผ๋ฏ๋ก ์น์ฌ์ดํธ ์ ์ฒด์ ๋งํฌ๋ฅผ ์ผ๊ด๋๊ฒ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. - ์คํด์ ์ง์ค:
- ์คํด: ๊ทธ๋ฅย
<a href="/clova/">
ย ์ฒ๋ผ ์ฃผ์๋ฅผ ์ง์ ์ฐ๋ ๊ฒ ๋ ์ฝ๋ค. - ์ง์ค: ๋น์ฅ์ ์ฌ์ ๋ณด์ด์ง๋ง, ๋์ค์ URL ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ๋ชจ๋ ํ
ํ๋ฆฟ์ ์ฐพ์ ์์ ํด์ผ ํ๋ 'ํ๋์ฝ๋ฉ์ ์ฌ์'์ ๋ง์ดํ๊ฒ ๋ฉ๋๋ค.ย
{% url %}
ย ์ฌ์ฉ์ ์ฅ๊ธฐ์ ์ผ๋ก ํจ์ฌ ํจ์จ์ ์ ๋๋ค. - Traceback (์ค๋ฅ ์ถ์ ๊ธฐ๋ก): ์ผ์์ ์ฌ์ ์
- 5์ด์๊ฒ ์ค๋ช ํ๋ค๋ฉด: ์ปดํจํฐ๊ฐ ์ผ์ ํ๋ค๊ฐ ๋ญ๊ฐ ์๋ชป๋๋ฉด, "๋ ์ฌ๊ธฐ์ ๋์ด์ก์ด!" ํ๊ณ ์๋ ค์ฃผ๋ ์ชฝ์ง์ผ. ์ด๋์ ์์ํด์ ์ด๋ค ๊ธธ์ ๊ฑฐ์ณ ์ด๋์ ๋ฌธ์ ๊ฐ ์๊ฒผ๋์ง ์์๋๋ก ์ ํ์์ด.
- ์ค์ํ ์์: ํ์ ์ด ๋ฒ์ฃ ํ์ฅ์์ ๋ฐ์๊ตญ์ ๋ฐ๋ผ๊ฐ๋ฉฐ ๋ฒ์ธ์ด ์ด๋์ ์์ ์ด๋๋ก ๊ฐ๋์ง ์ถ์ ํ๋ ๊ณผ์ ๊ณผ ๋น์ทํฉ๋๋ค. Traceback์ ์ฝ๋ ์คํ ๊ฒฝ๋ก๋ฅผ ์ญ์ถ์ ํ์ฌ ์ค๋ฅ ๋ฐ์ ์ง์ ์ ์๋ ค์ค๋๋ค.
- ์จ๊ฒจ์ง ์ค์์ฑ: Traceback์ ๋งจ ์๋ซ๋ถ๋ถ์ ์๋ ์ค์ ์ค๋ฅ ๋ฉ์์ง(
NoReverseMatch
)์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ผ ๋ฐ ์ฝ๋ ๋ผ์ธ ๋ฒํธ(django/urls/resolvers.py
,ยdjango/template/defaulttags.py
ย ๋ฑ)๊ฐ ๋ฌธ์ ํด๊ฒฐ์ ๊ฐ์ฅ ์ค์ํ ๋จ์์ ๋๋ค. - ์คํด์ ์ง์ค:
- ์คํด: Traceback์ ๋๋ฌด ๊ธธ๊ณ ๋ณต์กํด์ ์ฝ๊ธฐ ์ด๋ ต๋ค.
- ์ง์ค: ์ ์ฒด๋ฅผ ๋ค ์ดํดํ ํ์๋ ์์ต๋๋ค. ๋งจ ์๋์ ์ค๋ฅ ์ ํ๊ณผ ๋งจ ์(๋๋ ์ค๊ฐ)์ ๋ด ์ฝ๋ ํ์ผ(์:ย
webtools/views.py
,ยwebtools/tool_list.html
) ๊ด๋ จ ๋ถ๋ถ์ ์ค์ฌ์ผ๋ก ๋ณด๋ฉด ์์ธ์ ๋น ๋ฅด๊ฒ ํ์ ํ ์ ์์ต๋๋ค.
๐ฎ ๋ฏธ๋ ์ ๋ต ๋ฐ ์งํ
- ์๋ฐฉ ์ ๋ต:
- URL ์ด๋ฆ ๊ท์นํ: URL ๋ณ๋ช
์ ์ง์ ๋ ์ผ๊ด๋ ๊ท์น(์:ย
์ฑ์ด๋ฆ_๋ชจ๋ธ์ด๋ฆ_๋์
)์ ์ฌ์ฉํ๊ณ , ํญ์ ๋ค์์คํ์ด์ค(app_name
)๋ฅผ ์ง์ ํฉ๋๋ค. - ์ค์์ง์ค์ URL ์ ๋ณด ๊ด๋ฆฌ:ย
webtools.json
์ฒ๋ผ ์ธ๋ถ ํ์ผ์์ URL ๊ด๋ จ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ ๊ฒฝ์ฐ,ยurl_name
ย ๋์ ยreverse()
ย ํจ์๋ก ์์ฑ๋ ์ค์ URL ๊ฒฝ๋ก๋ฅผ ์ ์ฅํ๊ฑฐ๋,ยurl_name
์ ์ฌ์ฉํ ๋๋ ๋ฐ๋์ ์ ํํ ๋ค์์คํ์ด์ค๋ฅผ ํฌํจํ๋๋ก ํฉ๋๋ค. (get_all_webtools
ย ํจ์์์ยreverse('CLOVA:chat_interface')
๋ฅผ ํธ์ถํ์ฌยurl
ย ํค์ ์ ์ฅํ๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค.) - ํ ์คํธ ์๋ํ: URL ์์ฑ์ด ํฌํจ๋ ํ์ด์ง์ ๋ํด ๋จ์ ํ ์คํธ(Unit Test)๋ ํตํฉ ํ ์คํธ(Integration Test) ์ฝ๋๋ฅผ ์์ฑํ์ฌ URL ์ด๋ฆ ๋ณ๊ฒฝ ์ ์ค๋ฅ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์งํฉ๋๋ค.
- ์ฅ๊ธฐ์ ๊ณ ๋ ค์ฌํญ: ํ๋์ฝ๋ฉ๋ URL ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ง ์๊ณ Django์ URL ์์คํ
(
{% url %}
ย ํ๊ทธ,ยreverse()
ย ํจ์)์ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ๋ ์ต๊ด์ ์ฅ๊ธฐ์ ์ผ๋ก ์น์ฌ์ดํธ์ ์ ์ง๋ณด์์ฑ๊ณผ ์ ์ฐ์ฑ์ ํฌ๊ฒ ํฅ์์ํต๋๋ค. - ์ ๋ฌธ๊ฐ ์ฌ๊ณ ๋ฐฉ์: Django ์ ๋ฌธ๊ฐ๋ URL ๋ณ๊ฒฝ์ด ํ์ํ ๋ ํ
ํ๋ฆฟ ํ์ผ์ ์์ ํ๋ ๋์ ,ย
urls.py
ย ํ์ผ๊ณผ URL ๋ณ๋ช , ๋ค์์คํ์ด์ค๋ฅผ ๋จผ์ ํ์ธํ๊ณ ์์ ํฉ๋๋ค. ๋ํ, ์ค๋ฅ ๋ฐ์ ์ Traceback์ ์ฃผ์ ๊น๊ฒ ๋ถ์ํ์ฌ ๊ทผ๋ณธ ์์ธ์ ์ฐพ์ผ๋ ค๊ณ ๋ ธ๋ ฅํฉ๋๋ค. - ํ์ต ๋ก๋๋งต:
- ๊ธฐ์ด: Django ๊ณต์ ๋ฌธ์์ URL Dispatcher ๋ถ๋ถ์ ์ฝ๊ณ ย
path()
,ยname
,ยapp_name
,ย{% url %}
ย ํ๊ทธ์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ์ตํ๋๋ค. - ์ฌํ:ย
reverse()
,ยresolve()
ย ํจ์ ์ฌ์ฉ๋ฒ๊ณผ URL ํจํด ์์ฑ ๊ณ ๊ธ ๊ธฐ๋ฒ(์ ๊ทํํ์ ์ฌ์ฉ ๋ฑ)์ ํ์ตํฉ๋๋ค. - ์ค์ : ์ค์ ํ๋ก์ ํธ์์ ๋ค์ํ ์ข ๋ฅ์ URL์ ์ค๊ณํ๊ณ , ๋ค์์คํ์ด์ค๋ฅผ ํ์ฉํ์ฌ ์ฑ ๊ฐ์ URL์ ๊ด๋ฆฌํ๋ ์ฐ์ต์ ํฉ๋๋ค.
๐ ์ค์ ์ ์ฉ ์ฒญ์ฌ์ง
- ์ฆ์ ์ ์ฉ:
webtools/config/webtools.json
ย ํ์ผ์ ์ด์ด "AI ์ฑ๋ด" ๋๊ตฌ์ยurl_name
์ย'CLOVA:chat_interface'
๋ก ์์ ํ๊ณ ์ ์ฅํฉ๋๋ค.webtools/views.py
์ยget_all_webtools
ย ํจ์์์ 'AI ์ฑ๋ด'์ยurl
ย ๊ฐ์ยreverse('CLOVA:chat_interface')
๋ก ๋์ ์์ฑํ๋๋ก ์์ ํฉ๋๋ค. (์ด ๋ฐฉ๋ฒ์ด ๋ ๊ถ์ฅ๋ฉ๋๋ค.)docker-compose down && docker-compose up -d
ย ๋ช ๋ น์ผ๋ก ์ปจํ ์ด๋๋ฅผ ์์ ํ ์ฌ์์ํ์ฌ ์บ์๋ฅผ ๋น์ฐ๊ณ ๋ณ๊ฒฝ์ฌํญ์ ์ ์ฉํฉ๋๋ค.
- ์ค๊ธฐ ํ๋ก์ ํธ: ํ๋ก์ ํธ ๋ด ๋ชจ๋ ํ
ํ๋ฆฟ ํ์ผ์ ๊ฒํ ํ์ฌ ํ๋์ฝ๋ฉ๋ URL ๊ฒฝ๋ก(
href="/some/path/"
)๊ฐ ์๋์ง ํ์ธํ๊ณ , ์๋ค๋ฉดย{% url %}
ย ํ๊ทธ๋ฅผ ์ฌ์ฉํ๋๋ก ๋ฆฌํฉํ ๋งํฉ๋๋ค. ๋ชจ๋ ์ฑ์ยapp_name
์ ์ ์ํ๊ณ ๋ค์์คํ์ด์ค๋ฅผ ์ ์ฉํฉ๋๋ค. - ์๋ จ๋ ์ ๊ฒ:
- URL ํ๋ผ๋ฏธํฐ(์:ย
/blog/post/123/
)๋ฅผ ํฌํจํ๋ URL์ย{% url %}
ย ํ๊ทธ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์์ฑํ ์ ์์ต๋๊น? - ๋ค๋ฅธ ์ฑ์ URL์ ๋ค์์คํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ ํํ ์ฐธ์กฐํ ์ ์์ต๋๊น?
NoReverseMatch
ย ์ค๋ฅ ๋ฐ์ ์ Traceback์ ๋ณด๊ณ ์์ธ์ด ๋๋ ํ ํ๋ฆฟ ๋๋ ๋ทฐ ์ฝ๋๋ฅผ ์ฐพ์ ์ ์์ต๋๊น?- ์ถ๊ฐ ๋ฆฌ์์ค:
- [์ด๊ธ]ย Django ๊ณต์ ๋ฌธ์ - URL ๋์คํจ์ฒ
- [์ค๊ธ]ย Django Template Language - url tag
- [์ค๊ธ]ย Django URL reversing
- [๊ณ ๊ธ] Real Python ๋ฑ ๋ธ๋ก๊ทธ์ Django URL ๊ด๋ จ ์ฌ์ธต ํํ ๋ฆฌ์ผ
๐ ์ง์ ์์ถ ์์ฝ
Django์์ย NoReverseMatchย ์ค๋ฅ๋ย ์๋ URL ๋ณ๋ช ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค. ํ ํ๋ฆฟ์ย {% url %}ย ํ๊ทธ๋ ์ฝ๋์ย reverse()ย ํจ์์์ **์ ํํ URL ๋ณ๋ช ๊ณผ ๋ค์์คํ์ด์ค('์ฑ์ด๋ฆ:๋ณ๋ช ' ํ์)**๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ค๋ฅ ๋ฐ์ ์ย Traceback ๋งจ ์๋๋ฅผ ํ์ธํ์ฌ ์ด๋ค ์ด๋ฆ์ด ๋ฌธ์ ์ธ์ง ํ์ ํ๊ณ ,ย urls.py์์ ์ฌ๋ฐ๋ฅธ ์ด๋ฆ์ ์ฐพ์ ์์ ํ๋ฉด ํด๊ฒฐ๋ฉ๋๋ค. URL์ ํ๋์ฝ๋ฉํ๋ ๋์ ย ๋ณ๋ช ๊ณผย {% url %}ย ํ๊ทธ๋ฅผ ์ฌ์ฉํ๋ ์ต๊ด์ ์ ์ง๋ณด์์ฑ์ ํฌ๊ฒ ๋์ ๋๋ค.
๋๊ธ
๋๊ธ ๋ก๋ฉ ์ค...