Chapter 03. 장고의 Template Language
템플릿 언어(Template Language)는 장고 Template에서 사용할 수 있는 특별한 문법이며 템플릿 변수, 템플릿 필터, 템플릿 태그, 템플릿 코멘트가 있다.
템플릿 변수(Template Variable)
{{ 변수 }}
중괄호를 두번 열고 닫은 형태로 View에서 템플릿이 렌더될 때 해당 변수가 의미하는 값으로 변환된다.
템플릿 렌더링에서 .(점) 연산자는 lookup(조회)를 나타낸다
템플릿 시스템이 렌더하는 도중 변수 이름에서 점을 발견한다면 다음과 같은 순서대로 lookup을 한다
- dictionary - 변수를 사전으로 간주하고 점 뒤에서 Key값 조회
- attribute - 변수를 객체로 간주하고 객체의 내부 속성값 조회 혹은 함수 호출
- list - 변수를 리스트로 간주하고 점 뒤에서 Index조회
예제를 한번 보자
Case1. Dictionary
# shop/views.py
def home(request):
context = {}
shopping_bag = {
'apple': 3,
'banana': 4,
'kimchi': 2,
'pork': 3,}
context['shopping_bag'] = shopping_bag
return render(request, 'shop/index.html', context=context)
<!-- shop/templates/shop/index.html -->
{{shopping_bag.apple}}
<br>
{{shopping_bag.kimchi}}
3
2
위와 같은 view에서 shopping_bag이라는 딕셔너리를 context 변수에 넣어 렌더해주면 템플릿에서는 변수에 점 연산자를 덧붙여 key값에 접근할 수 있다
Case2. Attribute
# shop/views.py
class Shop:
def __init__(self) -> None:
self.name = "롯데슈퍼"
self.location = "서울 은평구"
self.rank = 17
def goal(self):
return self.rank - 5
def __str__(self) -> str:
return self.name + ' 은평점'
def home(request):
context = {}
shop = Shop()
context['shop'] = shop
return render(request, 'shop/index.html', context=context)
{{shop.name}}
<br>
{{shop.goal}}
<br>
{{shop}}
롯데슈퍼
12
롯데슈퍼 은평점
간단한 Shop클래스를 만들고 그 안에 __init__메서드 등 간단한 함수를 만들었다
Shop클래스를 통해 shop 인스턴스를 만들고 이를 context변수 안에 넣어 랜더하면 위 결과와 같이 객체에 접근할 수 있다
Case3. List
def home(request):
context = {}
team_list = ['아드리아누', '페페', '호날두', '메시', '카시야스']
context['team'] = team_list
return render(request, 'shop/index.html', context=context)
{{team.3}}
<br>
{{team.4}}
<br>
{{team.1}}
<br>
{{team.2}}
메시
카시야스
페페
호날두
위와 같이 team_list 리스트를 만들어 context 딕셔너리에 넣어 랜더했을 때 team.<인덱스> 형태로 접근할 수 있다
템플릿 필터(Template Filter)
{{ 변수|filter }}
{{ 변수|filter:args }}
템플릿 변수에 파이프(|)를 쓰고 템플릿 필터를 사용하면 템플릿 변수를 변환할 수 있다
Django에는 약 60여개의 내장 템플릿 필터가 있으며 개발자가 직접 필터를 정의할 수도 있다
아래는 몇 가지 템플릿 필터 예제이다
1. add : args만큼 더한다 ( + )
이 필터는 두 값을 모두 정수로 강제 변환하려고 시도한 뒤 실패하면 어쨌든 값을 추가하려고 시도한다.
정수로 강제 변환될 수 있는 문자열은 합산된다.
# shop/views.py
shopping_bag = {
'dumpling': "김치만두", # value가 문자열
'banana': [2, 4], # value가 리스트
'kimchi': 2, # value가 정수
'pork': 3.5,} # value가 실수
<!-- 문자열 -->
{{shopping_bag.dumpling|add:" 맛있다"}} <!-- 결과: 김치만두 맛있다 -->
<!-- 리스트 -->
{{shopping_bag.banana|add:5}} <!-- 결과: "" -->
{{shopping_bag.banana|add:"5"}} <!-- 결과: "" -->
{{shopping_bag.banana|add:[5,3]}} <!-- 결과: SyntaxError -->
{{shopping_bag.banana|add:shopping_bag.banana}} <!-- 결과: [2, 4, 2, 4] -->
<!-- 정수 -->
{{shopping_bag.kimchi|add:10}} <!-- 결과: 12 -->
{{shopping_bag.kimchi|add:"10"}} <!-- 결과: 12 -->
<!-- 실수 -->
{{shopping_bag.pork|add:5}} <!-- 결과: 8 -->
{{shopping_bag.pork|add:"5"}} <!-- 결과: 8 -->
{{shopping_bag.pork|add:5.5}} <!-- 결과: 8 -->
위 예제를 보면 리스트에 변수 형태가 아닌 연산은 수행할 수 없는 것으로 보이고, 정수에는 10을 주든 "10"을 주든 똑같은 결과가 나왔다. 실수는 정수 부분만 연산에 참여하는 것으로 보인다
2. addslashes : 따옴표(') 앞에 역슬래쉬(\)를 붙인다
3. capfirst : 첫 글자를 대문자로 변환한다. 첫 글자가 문자가 아니면 효과가 없다.
4. center : 주어진 너비의 필드 가운데 정렬한다
# shop/views.py
shopping_bag = {
'dumpling': "김치만두",
}
{{shopping_bag.dumpling|center:"20"}}
<h1>{{shopping_bag.dumpling|center:"20"}}</h1>
<textarea>{{shopping_bag.dumpling|center:"20"}}</textarea>
HTML에서 공백을 몇 개 쓰든 하나로 줄여서 표현해 주므로 화면 상에서는 공백이 표현 안된 것처럼 보인다.
(공백을 표현하고 싶다면 개행문자  를 이용하자)
하지만 페이지 소스보기를 하면 공백이 제대로 적용된 것으로 볼 수 있다
이외에도 날짜정보를 출력할 수 있는 date, 값이 없으면 다른 값을 출력시켜주는 default, 심지어 json형식으로 변환해주는 json_script 등 다양한 템플릿 필터가 있으므로 여기를 눌러 docs를 확인해보자
템플릿 태그(Template Tag)
{% tag %}
템플릿 언어의 꽃 템플릿 태그.
템플릿을 작성할 때 반복문, 조건문 등의 로직을 사용해서 마치 프로그래밍을 하듯 템플릿을 작성할 수 있다
기본적으로 제공하는 태그도 있지만 개발자가 직접 정의해서 사용할 수도 있다
1. for : iterable한 객체를 반복해 템플릿을 작성
# shop/views.py
shopping_bag = {
'dumpling': "김치만두", # value가 문자열
'banana': [2, 4], # value가 리스트
'kimchi': 2, # value가 정수
'pork': 3.5,} # value가 실수
<!-- shop/templates/shop/index.html -->
<h3>일반</h3>
{% for key, value in shopping_bag.items %}
{{key}}, {{value}}
<br>
{% endfor %}
<h3>역순!</h3>
{% for key, value in shopping_bag.items reversed %}
{{key}}, {{value}}
<br>
{% endfor %}
위와 같이 key와 value값을 반복 출력할 수 있다
reversed 키워드를 붙이면 역순으로 출력할 수도 있다
# shop/views.py
def home(request):
context = {}
numbers = []
context['numbers'] = numbers
return render(request, 'shop/index.html', context=context)
{% for number in numbers %}
{{number}}
<br>
{% empty %}
<p> 값이 없어요! </p>
{% endfor %}
값이 없어요!
만약 값이 비어있다면 {% empty %} 태그로 다른 값을 출력해 줄 수도 있다
2. if : 조건문의 형태로 템플릿을 작성
# shop/views.py
def home(request):
context = {}
shopping_bag = {
'dumpling': "김치만두", # value가 문자열
'banana': [2, 4], # value가 리스트
'kimchi': 2, # value가 정수
'pork': 3.5,} # value가 실수
context['shopping_bag'] = shopping_bag
return render(request, 'shop/index.html', context=context)
<!-- shop/templates/shop/index.html -->
{% for item in shopping_bag %}
{% if item == 'dumpling' %}
<p>만두를 고르셨습니다.</p>
{% elif item == 'kimchi' %}
<p>김치를 고르셨습니다.</p>
{% else %}
<p>나머지입니다.</p>
{% endif %}
{% endfor %}
위와 같이 if태그의 조건에 따라 다른 결과를 얻을 수 있다.
3. with : 복잡한 변수의 별명을 붙이기 위해서 사용하는 태그
# shop/views.py
def home(request):
context = {}
shopping_bag_full_of_apples = {
'apple': 6,
'green apple': 4,
'red apple': 2,
'pineapple': 8,}
context['shopping_bag_full_of_apples'] = shopping_bag_full_of_apples
return render(request, 'shop/index.html', context=context)
<!-- shop/templates/shop/index.html -->
{% with shopping_bag_full_of_apples as bag %}
{{ bag.pineapple }}
{% endwith%}
<br>
{{ shopping_bag_full_of_apples.pineapple}}
8
8
with태그 안에서 길고 복잡한 변수를 bag이라는 짧은 별명을 붙여 사용할 수 있다.
더 많은 템플릿 태그에 대한 설명은 여기 공식 docs를 확인하자.
템플릿 코멘트(Template Comment)
{# comments #}
{% comment %}
<p> comment with Multiple lines </p>
{% endcomment %}
템플릿 언어의 주석이며 한줄 혹은 여러줄로 작성할 수 있다.
템플릿 코멘트는 다른 템플릿 코멘트에 포함될 수 없다.
'프로그래밍 > Python' 카테고리의 다른 글
[Django] 장고 기초 - (4) Query Set(1) (2) | 2023.04.22 |
---|---|
[Django] 장고 기초 - (3) Models (0) | 2023.04.20 |
[Django] 장고 기초 - (1) 개요 및 개발 환경 구성 (0) | 2023.04.14 |
[Python] 자료형 특집 - (1) 시퀀스 타입(List/Tuple/Range) (0) | 2023.03.24 |
[Python] 함수 사용법 - (3) itertools (2) | 2023.03.22 |