본문 바로가기
WebFramework/Python Django

[Python Django] 8. DTL(Django Template Language)1 - extends와 block으로 HTML 뼈대 만들고 적용하기

by Rosmary 2024. 4. 9.
728x90
반응형

 

 

 

 

지금까지 필자의 Django 포스팅은 Django 프레임워크를 구성하는 파일의 종류와, 이들 파일을 조금씩 수정하면서 기능을 확인해본것이 전부였다. 이번 포스팅부터는 사용자가 접속하는 경우 어느정도 동작하는 Django 웹 서버를 구성해보려한다. 그 첫 번 째 주제로, 웹에서 가장 기본적으로 다루어야하는 HTML를 Django가 제공하는 DTL로 다룰 수 있는 방법에 대해 정리해보려한다.

 

 

 

1. Django 프로젝트 재구성.

 

(1) 프로젝트 및 앱 생성

 

필자는 필자가 사용하는 Linux 가상환경(CentOS 8)에서 바로 포스팅에 사용할 코드를 작성하려한다 - 필자의 Linux는 날 것 그대로의 vi 편집기라 자동 완성 따위(?)는 제공하지 않아 직접 코드를 익히기에 확실히 좋다 -  웹 접속 IP와 포트는 Linux에 지정된 IP와 기본 포트를 사용하며 이와 관련된 설정(방화벽 오픈, Listen Address 설정)은 사전에 미리 완료했다.

 

먼저 프로젝트부터 생성하자. 괜히 거창한 프로젝트 이름 지어봤자 어차피 몇 주 뒤면 다시 지울(?) 예정이니 간단히 tmp_django_svr라는 이름으로 만들어보려한다.

 

 

 

이번 포스팅에서 DB는 사용하지 않을 예정이라, migrate과 관련된 명령어는 모조리 건너뛰고 바로 서버를 실행해서 정상 구동되는지, 원격지에서 접속이 가능한지 확인해본다.

 

Migration 안 할 거냐고 빨간 글씨로 물어보긴 하는데, 본 포스팅에서는 문제가 없다.

 

 

이제 필자는 필자의 웹 서버에 구성할 앱을 추가해야한다. 아주 가볍게,

 

-  메인 화면 (/):  Welcome Page, root page로 동작. index.html. 

    -  나이 확인 (/age):  주민등록번호 앞 7자리 입력 시, 만 나이 / 한국식 나이 / 성별을 계산하는 페이지

          - 입력 페이지(/age):    index.html

          - 결과 출력 페이지(/age/result):    result.html

 

    -  국제전화번호검색(/telnum): 국제 전화번호 입력 시, 해당 번호를 사용하는 국가명 반환

          -  입력 페이지(/telnum):    index.html

          -  결과 출력 페이지(/telnum/result):    result.html

 

    -  구구단 출력(/gugu):  정수 타입의 단 입력 시, N X 9까지의 구구단을 테이블에 출력

         -  입력 페이지(/gugu):    index.html

         -  결과 출력 페이지(/gugu/{dan_number}):    result.html

 

만들어보려한다(이 무슨 해괴한 웹 사이트인가..).

 

 

위의 구조대로 앱을 생성(app_main, app_age, app_telnum, app_gugu)하고,

 

 

 

Web Projects의 settings.py 파일에 생성한 앱을 추가한다.

 

 

 

다음으로 각 어플리케이션에 templates 폴더, 각 URL에 매칭되어 랜더링 될 페이지 파일을 만들어준다.

 

 

 

마지막으로 생성한 각 어플리케이션 폴더에 메인 urls.py 파일에 include할 urls.py 파일을 생성해준다.

 

 

 

 

(2) urls.py, views.py 파일 작성

 

HTML 파일을 다루기 위한 프로젝트의 구성이 끝이 났다. 이제 프로젝트의 urls.py 파일을 아래와 같이 작성한다. 

 

 

 

path와 include 함수로 웹 페이지 주소와 주요 application의 urls.py 파일을 연결해 주었으므로 이제 각 앱의 urls.py도 수정한다. 필자는 각 app의 path 경로를 ""와 "result/" 두 가지만 두었으며, 이들은 각 application 폴더의 views.py의 index와 result 함수를 참조하도록 지정했다. 하위 구조에 대한 urls.py 및 views.py 작업이 완료되면 메인 페이지에 대한 urls.py와 views.py 작업도 진행한다.

 

 

 

여기까지 완료되었다면 서버를 구동하여 설계한 하위 주소의 페이지가 에러 없이 나타나는지 확인하자. 아직까지는 HTML 파일에 작업을 하지 않았기 때문에 브라우저에는 빈 화면이 나타나야 한다.

 

모든 경로가 에러 없이 정상 출력되는 것을 확인했다.

 

 

이제 본격적으로 Django로 HTML을 작성해보자.

 

 

 

2. Django Template Language

 

Django는 Flask와 유사하게 HTML에서도 동작이 가능한 Python 비스무리한 코드를 제공한다. 단, Flask와 동일하게 Jinja 모듈을 사용하는 것이 아니라 자체 템플릿 언어인 DTL(Django Template Language)를 사용한다.

 

사용 방법은 Jinja에서 제공하는 기능과 동일한 기능을 포함하여 몇 가지 추가적인 기능을 제공한다. 크게 4가지로 나뉜다.

1
2
3
4
5
I.  Variables (변수)
 
# Django view 모듈로부터 전달받은 데이터(변수)의 HTML 표시 시 사용
 
{{ VAR_NAME }}
cs

 

1
2
3
4
5
6
7
II.  Filter (필터)
 
# Variables와 함께 사용하며, 변수명 뒤에 파이프(|) 추가 후 필터 문법을 사용하여 변수 제어
 
{{ VAR_NAME|default:'nothing' }}
 
# ex) VAR_NAME 값이 존재하지 않으면 nothing을 기본값으로 지정
cs

 

1
2
3
4
5
6
7
III.  Tags (태그)
 
# Flask Jinja의 statement와 동일한 기능. 일부 Python 문법을 HTML 파일에 차용할 때 사용한다.
 
{% if VAR_NAME %}
...
{% endif %}
cs

 

1
2
3
4
5
IV.  Comments (주석)
 
# HTML 주석 <!-- --> 대신 사용
 
{# 주석 내용 추가 #}
cs

 

 

 

 

Jinja에 존재하지 않는 필터나 주석도 DTL에서는 제공하며 Jinja의 선언문에 해당하는 Tag 역시 조금 더 폭 넓은 기능을 지원한다. 그 중 하나가 {% extends %}, {% block %} 태그인데 이는 아래의 예시로 한 번 살펴보자.

 

 

 

 

3. extends, block 태그

 

 

(1) 배경

 

잠시 HTML로 돌아가서...HTML은 다른 HTML 파일을 include할 수 있는 <object>라는 태그를 제공한다.

참고로 왼쪽은 웹 브라우저에서 열은 main.html이다.

 

 

<object> 태그는 웹 페이지 내 공통되는 부분 - NAV, FOOTER, HEADER 등 - 을 별도의 파일로 미리 정의한 뒤, 개별 html 파일의 특정 부분에 정의된 내용을 include 할 수 있도록 만든다. 그러나 각 부분에 대해 별도로 HTML 문서를 작성해주어야 하기 때문에 HTML 구조에서 상당히 많이 벗어난 포맷이 파일에 작성되며, 이 때문에 직관적으로 이해가 어려워져 추후 코드 수정이 필요한 경우 시간이 많이 소요될 가능성이 있다는 문제가 있다.

 

실제 위 예제에서 사용한 include HTML 파일이다.

 

 

또한 <object> 태그는 브라우저에 따라 지원을 하지 않는 경우도 있기 때문에 모든 사용자에게 동일한 화면을 제공하지 못 할 수 있다는 문제점이 존재한다. 

 

다행히 Django는 DTL의 Tag를 통해 HTML의 뼈대가 되는 파일을 다른 HTML 파일에서 참조할 수 있도록 하는 기능을 제공한다. 이 때 사용하는 것이 {% extends %}와 {% block %} 태그다.

 

{% extends %}는 뼈대로 사용할 파일을 HTML 내에 Import 할 때 사용하며, {% block %} 태그는 각 HTML 파일마다 각기 다른 내용을 가져야하는 부분에 배치시킴으로써 <object> 태그와 유사하게 동작하도록 만들 수 있다.

 

 

(2) 뼈대 HTML 파일 생성 및 Django 설정

 

먼저 뼈대가 될 HTML 파일을 만들어, 프로젝트 폴더의 상단에 배치하고 settings.py의 templates 변수에서 이 폴더를 바라볼 수 있도록 설정해준다.

 

 

 

skeleton.html 파일은 모든 html 파일의 뼈대가 되는 파일로 공통 부분인 Header, Footer를 정의한다. 조금 더 나아가 Body의 메인 부분의 공통 적용 부분까지 파일을 작성한다면 아래와 같은 형태가 나타난다.

 

 

 

이제 skeleton.html 파일을 모든 HTML 파일에 공통적으로 적용하되, 변경이 있는 부분에는 {% block %} 태그를 적용한다. 단, 뼈대가 되는 HTML 파일에는 변경이 필요한 부분이 세 부분이므로, 이들 block을 구분하기 위해 {% block BLOCK_NAME %} 형태로 파일을 수정한다. 

 

 

이제 이 파일을 조금 전 생성한 최상위 templates 폴더 내에 위치시키면 된다.

 

 

 

(3) 뼈대 HTML 파일의 전체 적용

 

나머지 html 파일에서는 새로 생성한 뼈대 HTML 파일을 include 하기 위해 {% extends %} 태그를 사용한다. extends 태그 뒤에는 include 할 파일명을 홑따옴표로 감싸서 표시하면 된다. 예시로 main 페이지의 HTML에 적용하면 아래와 같은 형태가 된다.

 

 

 

모든 HTML 파일에 위 코드를 적용하고 서버를 구동해보자. 그러면 아래와 같이 어떤 페이지를 방문하더라도 Skeleton.html에서 정의한 Header와 Footer 형태가 고스란히 나타나는 것을 알 수 있다.

 

 

 

 

 

(4) 개별 파일의 내용 수정

 

마지막으로 개별 HTML 파일에서 수정해야 하는 부분에 대해서만 작업을 진행해보자. 지금은 skeleton.html 파일을 제외한 나머지 HTML 파일은 단순히 DTL 태그 한 줄 만 들어가 있다. 그럼 변경해야하는 내용은 어떻게 개별 파일에 넣어야할까?

 

skeleton.html 파일에는 변경이 필요한 부분에 block 태그를 추가해놓았다. 그리고 이 skeleton.html는 모든 HTML에 적용되어 있다. 그 말인 즉슨, block 태그를 개별 HTML 파일이 인식할 수만 있다면 변경이 필요한 내용만 수정을 할 수 있게 된다.

 

의외로 간단하다. 개별 HTML 파일에, 지정한 block 사이에 넣고자 하는 태그나 글을 넣어주면 된다. 현재 skeleton.html 파일은 title, subtitle, main 이라는 block 태그가 존재하므로, 이들 block 안에 작성하고자하는 내용을 추가하면 된다. 메인 페이지의 index.html부터 적용해보자.

 

 

 

메인 페이지를 장식하는 index.html 파일을 위와 같이 작성해서 저장하고 다시 서버를 구동하면, 웹 접속 시 나타나는 화면만 필자가 수정한 내용대로 나타나게 된다. 아래와 같이.

 

 

 


 

 

다음 포스팅에서는 오늘 만든 Django 서버 프로젝트를 기반으로 HTTP GET 통신을 진행해보려한다.

반응형

댓글