프로그래밍/Python

[Django] 장고 기초 - (2) Template Language

Churnobyl 2023. 4. 17. 11:14
728x90
반응형

 

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>

 

4. center의 결과

 

페이지 소스 보기

HTML에서 공백을 몇 개 쓰든 하나로 줄여서 표현해 주므로 화면 상에서는 공백이 표현 안된 것처럼 보인다.

(공백을 표현하고 싶다면 개행문자 &nbsp를 이용하자)

하지만 페이지 소스보기를 하면 공백이 제대로 적용된 것으로 볼 수 있다

 

이외에도 날짜정보를 출력할 수 있는 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 %}

 

for태그

위와 같이 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태그

위와 같이 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 %}

템플릿 언어의 주석이며 한줄 혹은 여러줄로 작성할 수 있다.

템플릿 코멘트는 다른 템플릿 코멘트에 포함될 수 없다.

반응형