Django 실습 (0414)

Sally·2026년 4월 14일

Django 프로젝트 1

문제 : articles 앱에 있는 catch함수에게 form tag의 GET method를 이용하여 데이터를 전달하고자 한다. 그러나 현재 작성된 form으로는 올바른 경로로 요청을 보내지 못하고 있다.
1) 올바르게 요청을 보낼 수 있도록 form을 수정한다.
2) 이렇게 보내진 데이터는 DTL을 사용하여 응답 페이지에서 렌더링 되어야 한다.

📁 프로젝트 구조

django_hw_2_2/
├── manage.py                        # Django 명령어 실행 도구
├── requirements.txt                 # 패키지 목록
│
├── form_practice/                   # 프로젝트 설정 폴더
│   ├── settings.py                  # 전체 설정
│   └── urls.py                      # URL 경로 관리
│
└── articles/                        # 앱 폴더
    ├── views.py                     # 요청 처리 함수
    └── templates/articles/
        ├── send.html                # 메시지 입력 폼
        └── receive.html             # 메시지 출력 페이지

Q) 폴더 구조 ?

django-admin startproject form_practice . # 프로젝트 생성
python manage.py startapp articles # 앱 생성

form_practice/articles/
생성 명령어startprojectstartapp
역할프로젝트 전체 설정특정 기능 담당
주요 파일settings.py, urls.pyviews.py, models.py, templates/
개수하나만 존재여러 개 가능

쉽게 비유하면:

form_practice = 건물 관리사무소 (전기, 수도, 출입구 관리)
articles = 건물 안의 방 (실제 기능이 있는 공간)

프로젝트가 커지면 아래와 같이 앱을 기능별로 분리하면 편하게 코드 관리할 수 있다.
form_practice/ ← 설정 (항상 하나)
articles/ ← 게시글 기능
users/ ← 유저 기능
comments/ ← 댓글 기능


1. MTV 패턴

Django는 MVC 패턴을 MTV라는 이름으로 사용한다.

MTVMVC역할
ModelModelDB 테이블 정의
TemplateView화면에 보여줄 HTML
ViewController요청 처리 & 로직

이름은 다르지만 구조는 동일하다. Django에서는 "화면"을 Template, "로직"을 View라고 부른다.

요청 흐름

브라우저 요청
    ↓
urls.py       → 어떤 view 함수를 실행할지 결정
    ↓
views.py      → 로직 처리, context 데이터 준비
    ↓
template      → context를 받아 HTML 렌더링
    ↓
브라우저 응답

2. 이번 과제 코드 설명

urls.py — URL 라우팅

from articles import views

urlpatterns = [
    path('send/', views.send),       # /send/ → send 함수
    path('receive/', views.receive), # /receive/ → receive 함수
]

/send/로 접속하면 views.send 함수를 실행하고,
/receive/로 접속하면 views.receive 함수를 실행한다.


views.py — 요청 처리

def send(request):
    return render(request, 'articles/send.html')

def receive(request):
    message = request.GET.get('message')  # URL 쿼리스트링에서 값 꺼내기
    context = {
        'message': message
    }
    return render(request, 'articles/receive.html', context)
  • send: 단순히 send.html을 보여주는 함수
  • receive: URL에 포함된 message 값을 꺼내서 template으로 전달
  • request.GET.get('message'): /receive/?message=안녕 에서 안녕을 꺼내는 코드
  • context: template에 넘겨줄 데이터를 딕셔너리로 포장

send.html — 데이터 전송 폼

<form action="/receive/">
  <input type="text" name="message">
  <input type="submit" value="[SEND]">
</form>
  • action="/receive/": submit 시 /receive/로 이동
  • name="message": 이 이름이 URL 쿼리스트링의 key가 됨
  • submit을 누르면 → /receive/?message=입력한값 형태로 요청

receive.html — 데이터 출력

<p>{{ message }}</p>
  • {{ }}: DTL(Django Template Language) 변수 출력 문법
  • views.py에서 context로 넘긴 message 값을 여기서 출력

전체 흐름 요약

① /send/ 접속
② 텍스트 입력 후 [SEND] 클릭
③ /receive/?message=안녕 으로 GET 요청
④ views.receive 실행 → request.GET.get('message') → "안녕"
⑤ context에 담아서 receive.html로 전달
⑥ {{ message }} 자리에 "안녕" 출력

3. Django에서 추가로 알아야 할 것

GET vs POST

GETPOST
데이터 위치URL 쿼리스트링요청 body
보안낮음 (URL에 노출)높음
용도조회생성, 수정, 삭제
Djangorequest.GETrequest.POST

이번 과제는 GET 방식이라 URL에 ?message=안녕이 노출됐다.
로그인, 회원가입 같은 민감한 데이터는 반드시 POST를 써야 한다.


DTL (Django Template Language) 주요 문법

<!-- 변수 출력 -->
{{ message }}

<!-- 조건문 -->
{% if message %}
  <p>{{ message }}</p>
{% else %}
  <p>메시지가 없습니다.</p>
{% endif %}

<!-- 반복문 -->
{% for item in items %}
  <p>{{ item }}</p>
{% endfor %}

render()의 세 번째 인자 context

context = {
    'message': message,
    'user': user,
}
return render(request, 'articles/receive.html', context)
  • context는 딕셔너리 형태로 전달
  • key 이름이 template에서 {{ key }} 로 사용됨
  • 여러 데이터를 한 번에 넘길 수 있음

CSRF (Cross-Site Request Forgery)

POST 방식의 form을 쓸 때는 반드시 {% csrf_token %}을 추가해야 한다.
없으면 Django가 요청을 거부한다.

<form action="/receive/" method="POST">
  {% csrf_token %}
  <input type="text" name="message">
  <input type="submit" value="[SEND]">
</form>

Django 프로젝트 2


1. 과제 개요

사용자가 URL에 담아 보낸 username 값을 받아서 자기소개 페이지를 보여주는 Django 프로젝트.

프로젝트 구조

django_hw_2_4/
├── manage.py
├── requirements.txt
│
├── my_pjt/                          # 프로젝트 설정 폴더
│   ├── settings.py
│   └── urls.py                      # URL 경로 관리
│
└── my_app/                          # 앱 폴더
    ├── views.py                     # 요청 처리 함수
    └── templates/my_app/
        └── introduce.html           # 자기소개 페이지

전체 흐름

① /my_pjt/introduce/?username=안서진 접속
② urls.py → views.introduce 함수 실행
③ request.GET.get('username') → "안서진" 꺼냄
④ context에 담아 introduce.html로 전달
⑤ {{ username }} → "안서진" 출력

핵심 코드

urls.py

path('my_pjt/introduce/', views.introduce)

views.py

def introduce(request):
    username = request.GET.get('username')
    context = {
        'username': username,
    }
    return render(request, 'my_app/introduce.html', context)

introduce.html

<h1>안녕하세요! 저는 {{ username }}입니다.</h1>

2. 질문 & 답

Q. views.py에서 username을 template으로 어떻게 전달해?

render()의 세 번째 인자 context가 전달 통로다.

username = request.GET.get('username')  # ① URL에서 값 꺼냄

context = {
    'username': username,               # ② 딕셔너리로 포장
}

return render(request, 'my_app/introduce.html', context)
#                                                ↑ ③ 여기서 template으로 전달

template에서는 {{ username }}으로 꺼내 쓴다.


Q. path('my_pjt/introduce/', views.introduce)는 뭐야?

URL과 함수를 연결하는 URL 지도다.

path('my_pjt/introduce/', views.introduce)
#     ↑                    ↑
#  이 URL로 접속하면    이 함수를 실행해

urlpatterns는 이런 연결 목록이다:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('my_pjt/introduce/', views.introduce),
]

Q. templates 안에 my_app 폴더를 또 만들어야 해?

앱이 여러 개일 때 이름 충돌을 방지하기 위해서다.

폴더를 안 만들면:

my_app/templates/introduce.html
users/templates/introduce.html   ← 이름 같아서 Django가 구분 못 함

폴더를 만들면:

my_app/templates/my_app/introduce.html    → 'my_app/introduce.html'
users/templates/users/introduce.html      → 'users/introduce.html'

views.py에서 경로로 구분 가능:

render(request, 'my_app/introduce.html', context)   # my_app 거
render(request, 'users/introduce.html', context)     # users 거

지금은 앱이 하나라 없어도 동작하지만, Django 공식 관례라 항상 만드는 게 좋다.


3. 추가로 알아야 할 것

쿼리스트링 (Query String)

GET 방식으로 데이터를 URL에 담아 보내는 방법.

http://127.0.0.1:8000/my_pjt/introduce/?username=안서진
                                         ↑
                                    쿼리스트링
  • ? 뒤부터가 쿼리스트링
  • key=value 형태
  • 여러 개는 &로 연결: ?username=안서진&age=25
  • Django에서 꺼낼 때: request.GET.get('key')

request.GET.get() vs request.GET[]

request.GET.get('username')      # 없으면 None 반환 (안전)
request.GET['username']          # 없으면 KeyError 발생 (위험)

항상 .get()을 쓰는 게 좋다. 기본값 지정도 가능하다:

request.GET.get('username', '익명')  # 없으면 '익명' 반환

DTL 변수 출력

{{ username }}           <!-- 변수 출력 -->
{{ username|upper }}     <!-- 대문자로 변환 -->
{{ username|length }}    <!-- 길이 출력 -->

| 뒤에 붙는 건 필터라고 하며, 값을 변환해서 출력할 수 있다.

profile
sally

0개의 댓글