Django가 요청을 받고 응답을 하는 과정은 다음과 같다.
요청(Request)이 들어오면 URL(urls.py)가 받아서 처리(처리할 뷰를 고름) ==> View(views.py) 처리(데이터를 읽어야 하면 DB에서 모델을 가져옴) ==> Template(html) 처리 ==> 응답(Response) 전달
이번에는 MTV 패턴을 실습하기 위해서 Template를 이해하고 view와 연결해보려고 한다.
#urls.py 파일
from django.contrib import admin
from django.urls import path
from articles import views
urlpatterns = [
path("admin/", admin.site.urls),
path("index/", views.index),
]
여기서 urlpatterns는 어떤 url 패턴으로 들어왔을 때 어디 뷰로 보낼지를 결정하는 것이다.
path는 path("어떤 url 패턴으로 들어오면", 여기로 보내)를 나타낸다.
※여기서 경로를 적을 때 url에 /를 붙이는 것을 Trailing Slash라고 한다. Django에서는 /를 넣어주는 것을 권장하기 때문에 꼭 넣어주도록 하자. (혹시 다시봐서 기억이 안난다면 검색해볼것)
지금까지 실습을 통해서 artilce 앱을 만들었는데 article 앱 안에 있는 views.py 파일에 index 함수를 만들어 주도록 하자.
※ 뷰를 작성하는 방법에 함수형 뷰와 클래스형 뷰가 있지만 장고를 처음 배울 땐 함수형 뷰가 흐름이 다 보여서 좋기 때문에 view 안에 전부 함수형 뷰로 작성할 예정이다.
# views.py 파일
from django.http import HttpResponse
def index(request):
response = HttpResponse("<h1>Hello, Django!</h1>")
return response
HttpResponse안에는 response로 주고 싶은 html코드를 적으면 된다.
이제 흐름을 살펴보면 /index/ 로 요청이 들어오면 views.index를 통해 views.py 파일로 가서 index 함수를 실행한다.
그러면 resopnse를 생성하고 응답을 해주는 것이다.
그런데 만약에 HTML 코드가 길어지면 저기안에 다 적어야 하나? 그렇게 하고 싶지 않은데...
그래서 HTML파일을 만들어서 그 파일을 뷰로 사용하는 방법에 대해 알아보려고 한다.
# views.py 파일
from django.shortcuts import render
def index(request):
return render(request, "index.html")
<!-- my_first_pjt/articles/templates/index.html 파일 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My First Django PJT</title>
</head>
<body>
<h1>My First Django Project</h1>
<p>My first Django project is working!</p>
</body>
</html>
이제 전체적인 흐름을 살펴보면 /index/ 로 요청이 들어왔을 때 index 뷰로 가서 render함수를 실행한다.
render함수는 index.html 파일을 가져와서 렌더링을 거쳐 HTML 파일을 보여준다.
(Django에서의 Template은 데이터를 보여주는 로직을 작성하는 부분이다.)
※ 나는 index.html 파일의 경로를 지정해준 것도 아닌데 어떻게 찾았지?
settings.py의 TEMPLATES를 찾아보면 "APP_DIRS": True 를 확인할 수 있는데 이건 APP 디렉토리 안쪽을 뒤져서 templates 디렉토리가 있으면 거기서 파일을 찾아준다.
Django Template Language (DTL)
Django Template 안에서만 사용하는 문법으로 Python에 익숙할 Django 개발자를 위해 Python과 비슷하게 되어 있지만 Python이 동작하는 것이 아니라 DTL이 동작하는 것이다.
여기서는 크게 변수, 필터, 태그, 주석에 대해서 알아보려고 한다.
<!-- 변수의 기본 형태 -->
{{ variable }}
<!-- 필터의 기본 형태 -->
{{ variable|filter }}
<!-- 필터 사용 예시(소문자로) -->
{{ first_name|lower }}
<!-- 태그의 기본 형태 -->
{% tag %}
<!-- 태그 사용 예시(조건문) -->
{% if ~ %}
{% endif %}
<!-- 주석의 기본 형태 -->
{# 한 줄 주석 #}
{% comment %}
여러줄
주석
{% endcomment %}
1. 변수
- view의 context로 넘긴 데이터를 접근할 수 있다.
- .(dot) 을 사용하여 변수의 속성값에 접근이 가능하다.
- render() 의 세번째 인자인 context에 dict 형태로 넘겨진 데이터 중 key 값이 template에서 사용 가능한 변수가 된다.
2. 필터
- 변수에 어떠한 작업을 추가적으로 더해 수정하고 싶을때 사용한다.
- 약 60개의 built-in template filter가 제공되며 일부 필터는 인자를 받기도 한다. (공식문서를 찾아 필요한 것을 가져다 쓸 것)
3. 태그
- 반복문 또는 논리, 조건문을 수행하여 제어 흐름을 만들거나 특수한 기능을 수행할 때 사용한다.
- 일부는 시작 태그와 종료 태그가 있다(위의 조건문 처럼, 또는 반복문)
4. 주석: 주석은 그냥 주석이지
블로그에는 따로 코드를 추가하는 내용들을 넣지 않고 실습을 하고 있지만 지금까지 많은 코드를 수정하고 templates를 만들었다. 이 과정에서 코드가 중복되는 불편함을 느끼며(가스라이팅을 당한듯 하지만) 이 문제를 해결하기 위해 Django는 템플릿 상속을 지원한다는 정보를 듣고 바로 적용해보려고 한다.
<!-- base.html 파일 -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
{% block content %}
{% endblock content %}
</body>
</html>
위의 코드는 앞으로 다른 html파일의 기본이 될 파일로 {% block block_name %} {% endblock block_name %} 부분이
상위 템플릿에서 하위 템플릿 마다 달라질 부분을 정의하는 것이다.
<!-- 위의 index.html 파일을 수정 -->
{% extends "base.html" %}
{% block content %}
<h1>My First Django Project</h1>
<p>My first Django project is working!</p>
{% endblock content %}
여기서 {% extends 'template_name' %} 부분은 하위 템플릿에서 상위 템플릿을 상속해서 확장한다는 것으로
템플릿의 가장 최상단에 위치해야한다.
근데 내가 base.html파일을 article앱만이 아니라 다른 앱에서도 쓰기 위해서 가장 상위 디렉토리의 templates 디렉토리를 만들어서 넣으면 Django는 위에서 말했듯이 APP을 돌면서 templates안에 파일이 있는지 찾기 때문에 base.html파일이 APP안에 templates에 없으면 참조가 안된다.
이 문제를 해결하기 위해 settings.py파일에 들어가서 커스텀 템플릿 경로를 추가해줘야 한다.
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
},
]
옵션은 좀 지우고(아직 몰라도 됨) 비워져 있던 DIRS에 BASE_DIR / "templates"를 추가했다.
※ BASE_DIR 가 뭔데?
Django가 친절하게 사용자들이 참조하는 디렉토리를 보니 프로젝트 최상단 경로값을 많이 참조한다는 점을 알아서 그 위치를 변수안에 넣어준 것이다. 이후에는 APP안 뿐만 아니라 프로젝트 최상단 경로의 templates를 뒤져서 원하는 파일이 있는지 확인할 수 있다.
'웹 개발' 카테고리의 다른 글
[Django] 다중 앱을 위한 URL 분리 (0) | 2024.08.20 |
---|---|
[Django] HTTP form으로 데이터 다루기 (0) | 2024.08.17 |
[Django] Django 이해하기 (0) | 2024.08.09 |
[Django] Django 시작하기 (0) | 2024.08.08 |
[웹 개발]가위바위보 게임 홈페이지 만들기 (0) | 2024.07.04 |