๐Ÿ“ฑ Django๋กœ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งŒ๋“ค๊ธฐ

Hyeonio_oยท2025๋…„ 6์›” 26์ผ

BackEnd

๋ชฉ๋ก ๋ณด๊ธฐ
4/9
post-thumbnail

Django๋ฅผ ํ™œ์šฉํ•ด ๊ฐ„๋‹จํ•œ ์ฑ„ํŒ… ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋‹จ๊ณ„๋ณ„ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค. URL ๋ผ์šฐํŒ…๋ถ€ํ„ฐ HTMX๋ฅผ ํ™œ์šฉํ•œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊นŒ์ง€ ์ฐจ๊ทผ์ฐจ๊ทผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๐ŸŽฏ ๋ชฉํ‘œ

  • Django์˜ URL ํŒจํ„ด๊ณผ View ๊ตฌ์กฐ ์ดํ•ด
  • Template ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•œ UI ๊ตฌ์„ฑ
  • HTTP ๋ฉ”์„œ๋“œ(GET, POST)์˜ ์ฐจ์ด์  ํ•™์Šต
  • HTMX๋ฅผ ์ด์šฉํ•œ ๋น„๋™๊ธฐ ํ†ต์‹  ๊ตฌํ˜„

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์„ค์ •

1. URLs ํŒจํ„ด ๊ตฌ์„ฑ

๋จผ์ € ์ฑ„ํŒ… ์•ฑ์˜ URL ๊ตฌ์กฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“„ chat/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index),
]

๐Ÿ“„ config/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('chat/', include('chat.urls')),
]

๐Ÿ’ก ํฌ์ธํŠธ: include('chat.urls')๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด chat ์•ฑ์˜ ๋ชจ๋“  URL์— chat/ ์ ‘๋‘์‚ฌ๊ฐ€ ์ž๋™์œผ๋กœ ๋ถ™์Šต๋‹ˆ๋‹ค.


๐ŸŽจ ํ…œํ”Œ๋ฆฟ ์‹œ์Šคํ…œ ๊ตฌ์ถ•

2. ๊ธฐ๋ณธ HTML ํ…œํ”Œ๋ฆฟ ์ƒ์„ฑ

Django์˜ ํ…œํ”Œ๋ฆฟ ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•ด ๋™์  ์›นํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๐Ÿ“„ chat/templates/chat/index.html

  • HTML ๊ธฐ๋ณธ ๊ตฌ์กฐ ์ƒ์„ฑ
  • Pico CSS CDN ๋งํฌ ์ถ”๊ฐ€
  • HTMX ์Šคํฌ๋ฆฝํŠธ ํฌํ•จ

3. View์—์„œ ํ…œํ”Œ๋ฆฟ ๋ Œ๋”๋ง

๐Ÿ“„ chat/views.py

def index(request):
    return render(request, "chat/index.html")

๐Ÿ’ก Django ํ…œํ”Œ๋ฆฟ ์‹œ์Šคํ…œ: render() ํ•จ์ˆ˜๋Š” ์•ฑ๋ช…/templates/ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์ž๋™์œผ๋กœ ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ์ฐพ์•„์ค๋‹ˆ๋‹ค.


๐Ÿ”„ HTTP ๋ฉ”์„œ๋“œ ์ดํ•ดํ•˜๊ธฐ

HTTP ๋ฉ”์„œ๋“œ์˜ ํŠน์ง•

๋ฉ”์„œ๋“œ์šฉ๋„ํŠน์ง•์˜ˆ์‹œ
GET๋ฐ์ดํ„ฐ ์กฐํšŒ์•ˆ์ „ํ•จ, ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์—†์Œ๊ฒ€์ƒ‰, ํŽ˜์ด์ง€ ๋กœ๋“œ
POST๋ฐ์ดํ„ฐ ์ƒ์„ฑ/์ˆ˜์ •๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํผ ์ œ์ถœ, ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€
PUT/PATCH๋ฐ์ดํ„ฐ ์ˆ˜์ •ํŠน์ • ๋ฆฌ์†Œ์Šค ์—…๋ฐ์ดํŠธํ”„๋กœํ•„ ์ˆ˜์ •
DELETE๋ฐ์ดํ„ฐ ์‚ญ์ œ๋ฆฌ์†Œ์Šค ์ œ๊ฑฐ๊ณ„์ • ์‚ญ์ œ

โš ๏ธ ์ฃผ์˜: HTML <form> ํƒœ๊ทธ๋Š” GET๊ณผ POST๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. PUT, DELETE ๋“ฑ์€ JavaScript API๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ’ฌ ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ ๊ตฌํ˜„

4. ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ View ์ถ”๊ฐ€

๐Ÿ“„ chat/views.py

def chat_message_new(request: HttpRequest) -> HttpResponse:
    question = request.POST.get("question", "")
    if question:
        answer = f"๐Ÿค– ๋‹น์‹ ์˜ ์งˆ๋ฌธ: {question}"
    else:
        answer = "โ“ ์งˆ๋ฌธ์ด ์ž…๋ ฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
    
    return HttpResponse(answer)

5. URL ํŒจํ„ด ์—ฐ๊ฒฐ

๐Ÿ“„ chat/urls.py

urlpatterns = [
    path("", views.index),
    path("messages/new/", views.chat_message_new),  # ์ƒˆ URL ํŒจํ„ด ์ถ”๊ฐ€
]

๐ŸŒ Query Parameters vs POST Data

Query Parameters ์ดํ•ดํ•˜๊ธฐ

Query Parameters๋Š” URL ๋’ค์— ?key=value&key2=value2 ํ˜•ํƒœ๋กœ ๋ถ™๋Š” ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

์˜ˆ์‹œ: https://example.com/search?q=django&category=tutorial&page=1

Django์—์„œ์˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ•:

# GET ์š”์ฒญ
question = request.GET.get("question", "")

# POST ์š”์ฒญ  
question = request.POST.get("question", "")

๐Ÿ”’ CSRF ๋ณด์•ˆ ์ดํ•ดํ•˜๊ธฐ

CSRF ํ† ํฐ์ด๋ž€?

CSRF (Cross-Site Request Forgery): ์‚ฌ์šฉ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€ ์š”์ฒญ์„ ๊ณต๊ฒฉ์ž๊ฐ€ ๋Œ€์‹  ๋ณด๋‚ด๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค.

<form method="POST">
  {% csrf_token %}  <!-- Django๊ฐ€ ์ž๋™์œผ๋กœ ๋ณด์•ˆ ํ† ํฐ ์ƒ์„ฑ -->
  <!-- ํผ ๋‚ด์šฉ -->
</form>

๐Ÿ›ก๏ธ ๋ณด์•ˆ ํŒ: POST, PUT, DELETE ๋“ฑ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ชจ๋“  ์š”์ฒญ์—๋Š” CSRF ํ† ํฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


โšก HTMX๋กœ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌํ•˜๊ธฐ

๊ธฐ์กด JavaScript vs HTMX

๊ธฐ์กด ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ :

  • ๋ณต์žกํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์„ค์ •
  • fetch API์™€ Promise ์ฒ˜๋ฆฌ
  • DOM ์กฐ์ž‘ ์ฝ”๋“œ ํ•„์š”
  • ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๋ณต์žก

HTMX ๋ฐฉ์‹์˜ ์žฅ์ :

<form hx-post="/chat/messages/new/" hx-target="#chat-response">
  {% csrf_token %}
  <input type="text" name="question" />
  <input type="submit" value="์ „์†ก" />
</form>
<div id="chat-response"></div>

HTMX ์†์„ฑ ์„ค๋ช…

์†์„ฑ์„ค๋ช…์˜ˆ์‹œ
hx-postPOST ์š”์ฒญ์„ ๋ณด๋‚ผ URLhx-post="/api/submit"
hx-target์‘๋‹ต์„ ํ‘œ์‹œํ•  ์š”์†Œ ์„ ํƒ์žhx-target="#result"
hx-getGET ์š”์ฒญ์„ ๋ณด๋‚ผ URLhx-get="/api/data"
hx-trigger์ด๋ฒคํŠธ ํŠธ๋ฆฌ๊ฑฐ ์„ค์ •hx-trigger="click"

๐ŸŽจ Pico CSS๋กœ ์Šคํƒ€์ผ๋ง

Pico CSS ํŠน์ง•

  • ๊ฒฝ๋Ÿ‰ํ™”: ์ตœ์†Œํ•œ์˜ CSS๋กœ ๊น”๋”ํ•œ ๋””์ž์ธ
  • ๋ฐ˜์‘ํ˜•: ๋ชจ๋ฐ”์ผ ์นœํ™”์ 
  • ๋น ๋ฅธ ์ ์šฉ: CDN์œผ๋กœ ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

์ฃผ์š” ํŠน์ง•

  • .container ํด๋ž˜์Šค๋กœ ์ค‘์•™ ์ •๋ ฌ
  • ๊ธฐ๋ณธ HTML ํƒœ๊ทธ์— ์ž๋™ ์Šคํƒ€์ผ ์ ์šฉ
  • ํผ ์š”์†Œ๋“ค์˜ ์ž๋™ ์Šคํƒ€์ผ๋ง

๐Ÿš€ ๊ฐœ๋ฐœ ๋‹จ๊ณ„๋ณ„ ์‹คํ–‰ ๊ฒฐ๊ณผ

1. ์ดˆ๊ธฐ ์„ค์ • ์™„๋ฃŒ

  • http://127.0.0.1:8000/chat ์ ‘์†
  • "hello django in html" ๋ฉ”์‹œ์ง€ ํ™•์ธ

2. ํผ ์ถ”๊ฐ€ ํ›„

  • ์งˆ๋ฌธ ์ž…๋ ฅ์ฐฝ๊ณผ ์ „์†ก ๋ฒ„ํŠผ ํ‘œ์‹œ
  • Pico CSS ์ ์šฉ์œผ๋กœ ๊น”๋”ํ•œ ๋””์ž์ธ

3. ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ ๊ตฌํ˜„ ํ›„

  • ์งˆ๋ฌธ ์ž…๋ ฅ ํ›„ ์ „์†ก ์‹œ ์‘๋‹ต ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
  • HTMX๋กœ ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ ์—†์ด ๋™์ž‘

4. ์ตœ์ข… ์™„์„ฑ

  • ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์ธํ„ฐํŽ˜์ด์Šค ์™„์„ฑ
  • ๋น„๋™๊ธฐ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ ๊ตฌํ˜„

๐Ÿ”ง ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

์ฃผ์š” ์ด์Šˆ์™€ ํ•ด๊ฒฐ์ฑ…

  1. "์งˆ๋ฌธ ์—†์Œ" ์˜ค๋ฅ˜

    • ์›์ธ: GET ์š”์ฒญ์œผ๋กœ POST ๋ฐ์ดํ„ฐ ์ ‘๊ทผ
    • ํ•ด๊ฒฐ: request.POST.get() ์‚ฌ์šฉ
  2. JavaScript ๋ณต์žก์„ฑ

    • ์›์ธ: ๋ณต์žกํ•œ fetch API์™€ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
    • ํ•ด๊ฒฐ: HTMX๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋Œ€์ฒด
  3. CSRF ํ† ํฐ ๋ˆ„๋ฝ

    • ์›์ธ: POST ์š”์ฒญ์— ๋ณด์•ˆ ํ† ํฐ ์—†์Œ
    • ํ•ด๊ฒฐ: {% csrf_token %} ์ถ”๊ฐ€

๐Ÿ“š ํ•™์Šต ํฌ์ธํŠธ

Django ํ•ต์‹ฌ ๊ฐœ๋…

  1. URL ๋ผ์šฐํŒ…: urls.py์—์„œ URL ํŒจํ„ด ์ •์˜
  2. View ํ•จ์ˆ˜: ์š”์ฒญ์„ ๋ฐ›์•„ ์‘๋‹ต์„ ๋ฐ˜ํ™˜
  3. Template ์‹œ์Šคํ…œ: HTML๊ณผ Django ํƒœ๊ทธ ์กฐํ•ฉ
  4. HTTP ๋ฉ”์„œ๋“œ: GET๊ณผ POST์˜ ์ ์ ˆํ•œ ์‚ฌ์šฉ

์›น ๊ฐœ๋ฐœ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

  1. ๋ณด์•ˆ: CSRF ํ† ํฐ์œผ๋กœ ๋ณด์•ˆ ๊ฐ•ํ™”
  2. ์‚ฌ์šฉ์ž ๊ฒฝํ—˜: HTMX๋กœ ๋ถ€๋“œ๋Ÿฌ์šด ์ธํ„ฐ๋ ™์…˜
  3. ๋””์ž์ธ: Pico CSS๋กœ ๋น ๋ฅธ ์Šคํƒ€์ผ๋ง
  4. ์ฝ”๋“œ ํ’ˆ์งˆ: ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ ์ž‘์„ฑ

๐Ÿš€ ๋‹ค์Œ ๋‹จ๊ณ„

  1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™: ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€ ์ €์žฅ
  2. ์‹ค์‹œ๊ฐ„ ๊ธฐ๋Šฅ: WebSocket ๋˜๋Š” Server-Sent Events
  3. ์‚ฌ์šฉ์ž ์ธ์ฆ: ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ ์‹œ์Šคํ…œ
  4. API ๊ตฌ์ถ•: REST API๋กœ ํ™•์žฅ

๐Ÿ’ช ๋„์ „ ๊ณผ์ œ: ์ด ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋” ๋ณต์žกํ•œ ์ฑ„ํŒ… ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด๋ณด์„ธ์š”!

0๊ฐœ์˜ ๋Œ“๊ธ€