본문 바로가기
PROGRAMMING/Django

[Django] DTL(Django Template Language), Template 상속

by 안녕나는현서 2021. 9. 2.
728x90

Django Template Language (DTL)

  • django template에서 사용하는 built-in template system
  • 조건, 반복, 변수 치환, 필터 등의 기능 제공
  • 단순히 Python이 HTML에 포함 된 것이 아니며, 프로그래밍적 로직이 아니라 프레젠테이션을 표현하기 위한 것
  • Python처럼 일부 프로그래밍 구조(if, for 등)를 사용할 수 있지만, 이것은 해당 Python 코드로 실행되는 것이 아님

 

DTL Syntax

1. Variable

  • render()를 사용하여 views.py에서 정의한 변수를 template 파일로 넘겨 사용하는 것
  • 변수명은 영어, 숫자와 밑줄(_)의 조합으로 구성될 수 있으나 밑줄로는 시작 할 수 없음
    • 공백이나 구두점 문자 또한 사용할 수 없음
  • dot(.)를 사용하여 변수 속성에 접근할 수 있음
  • render()의 세번째 인자로 {'key': value} 와 같이 딕셔너리 형태로 넘겨주며,
    여기서 정의한 key에 해당하는 문자열이 template에서 사용 가능한 변수명이 됨 {{ variables }}
# articles > views.py

def greeting(request):
    name = '춘식'
    age = 10

    foods = ['고구마', '우유']
    
    info = {
        'hobby' : 'dance',
        'freind' : 'lion'
    }

    context = {
        'name' : name,
        'age' : age,
        'foods' : foods,
        'info' : info
    }

    return render(request, 'greeting.html', context)
<!-- articles > templates > greeting.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>안녕하세요! {{ name }}입니다.</h1>
  <p>나이는 {{ age }}입니다.</p>

  <p>제가 좋아하는 음식은 {{ foods }}입니다.</p>
  <p>가장 좋아하는 음식은 {{ foods.0 }}입니다.</p>

  <p>저의 취미는 {{ info.hobby }}입니다.</p>
  <p>가장 친한 친구는 {{ info.freind }}입니다.</p>
</body>
</html>

http://127.0.0.1:8000/greeting/

 

2. Filters

  • 표시할 변수를 수정할 때 사용
  • 파이프(|)를 사용하여 적용

3. Tags

  • 출력 텍스트를 만들거나, 반복 또는 논리를 수행하여 제어 흐름을 만드는 등 변수보다 복잡한 일들을 수행
  • 일부 태그는 시작과 종료 태그가 필요 {%tag %} ... {% endtag %}

 

# articles > views.py

def dinner(request):
    foods = ['salad', 'chicken', 'salmon']
    pick = random.choice(foods)

    context = {
        'foods' : foods,
        'pick' : pick
    }

    return render(request, 'dinner.html', context)
<!-- articles > templates > dinner.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1> 오늘 저녁은 {{pick}} 입니다! </h1>
  {% comment %} Filters {% endcomment %}
  <p> {{pick}}은 {{pick|length}}글자입니다. </p>
  <p> {{foods|join:', '}} </p>

  <h1>메뉴판</h1>
  <ul>
    {% comment %} Tags {% endcomment %}
    {% for food in foods %}
    <li> {{food}} </li>
    {% endfor %}
  </ul>
</body>
</html>

 

4. Comments

  • 한 줄 주석 : {# #}
  • 여러 줄 주석 : {% comment %} {% endcomment %}

 

Template inheritance (템플릿 상속)

  • 템플릿 상속은 기본적으로 코드의 재사용성에 초점을 맞춤
  • 템플릿 상속을 사용하면 사이트의 모든 공통 요소를 포함하고,
    하위 템플릿이 재정의(override) 할 수 있는 블록을 정의하는 기본 “skeleton” 템플릿을 만들 수 있음

 

- html 파일의 경우, 파일마다 기본 html 구조를 계속 반복하여 정의해줘야함
  → 프로젝트와 같은 레벨에 templates 폴더를 생성 후, base.html에 기본 구조를 입력한 뒤 상속해보자!

 

1. 장고는 기본적으로 앱(여기에서는 articles) 내부의 templates 폴더만 탐색 가능

  • 프로젝트에 있는 templates 폴더를 탐색할 수 있도록 경로 추가
    프로젝트 > setting.py > TEMPLATES > 'DIRS' 에 경로 추가
  • BASE_DIR : manage.py가 있는 레벨의 폴더
# fistpjt > setting.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

 

2. base.html 생성

<!-- templates > base.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  {% comment %}
    모든 화면에서 공통으로 보이는 영역을 이 곳에 정의할 수 있음
    ex ) 네비게이션, 푸터
  {% endcomment %}
  <nav>네비게이션 바!</nav>

  {% comment %} 
    하위 템플릿에서 재지정(overriden)할 수 있는 블록 정의
    하위 템플릿이 채우는 공간
  {% endcomment %}
  {% block content %}
  {% endblock  %}

  <footer>푸터!</footer>
</body>
</html>

 

3. 각각의 html 파일이 상속받을 수 있도록 태그 작성

  • {%  extends '' %} : 자식(하위)템플릿이 부모 템플릿을 확장한다는 것을 알림
  • 반드시 템플릿 최상단에 작성 되어야 함
<!-- articles > templates > index.html -->

{% extends 'base.html' %}

{% block content %}
  <h1>만나서 반가워요!</h1>
{% endblock  %}

 

Django Templates system

  • 표현과 로직(view)을 분리
    • 템플릿 시스템은 표현을 제어하는 도구이자 표현에 관련된 로직일 뿐이라고 생각한다.
    • 즉, 템플릿 시스템은 이러한 기본 목표를 넘어서는 기능을 지원하지 말아야 한다.
  • 중복을 배제
    • 대다수의 동적 웹사이트는 공통 header, footer, navbar 같은 사이트 공통 디자인을 갖는다.
    • Django 템플릿 시스템은 이러한 요소를 한 곳에 저장하기 쉽게 하여 중복 코드를 없애야 한다.
728x90

댓글