본문 바로가기

Back-end & Server/Django

[Django] 템플릿

728x90
반응형

이전 글에서는 HttpResponse() 함수를 사용할 때 HTML을 하드코딩에서 넘겼음.

  • 별로 좋은 방법이 아님
  • 웹 페이지 코드와 파이썬 코드를 분리하는 것이 바람직함

 

템플릿(Template)

Django의 템플릿은 문서의 표시를 데이터와 분리하기 위한 텍스트 문자열임

  • 자리표시 - 문서를 표시하는 방법을 조절
  • 기본로직(탬플릿 태그) - 다양한 비트 정의
 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

  • 모든 텍스트 기반 형식을 생성할 수 있음 

Django 프로젝트는 하나 또는 여러 개의 템플릿 엔진으로 구성될 수 있음

DTL(Django Template Language) 자체 템플릿 시스템을 위한 빌트인 백엔드를 제공

사용 과정

  • 원시 템플릿 코드를 문자열로 제공해 템플릿 객체를 만듬
  • 주어진 변수 세트를 사용해 템플릿 객체의 render() 메서드 호출
    • 완전히 렌더링된 템플릿이 문자열로 반환, 모든 변수와 템플릿 태그는 콘텍스트에 따라 계산

 

템플릿 객체 만들기

템플릿 클래스는 django.template 모듈에 있고 생성자는 원시 템플릿 코드인 하나의 인수를 취함

  • Template()

템플릿 코드에 구문 오류가 있는 경우 Template()을 호출하면 TemplateSyntaxError 예외가 발생함

from django.template import Template
# 객체 = Template(템플릿 문자열)
t = Template('My name is {{ name }}.')

 

템플릿 렌더링

템플릿 객체가 있으면 콘텍스트 정보를 지정해 데이터를 전달 할 수 있음.(django.template 모듈에 있음)

  • Context()
from django.template import Template,Context

t = Template('My name is {{ name }}.')
c = Context({'name':'Pupbani'})

name 변수에 Pupbani를 지정함

이렇게 템플릿, 콘텍스트 객체를 만들면 render() 메서드를 호출함

t.render(c)

이렇게 렌더링 된 템플릿HttpResponse()로 전달해 뷰에 표시할 수 있음

from django.template import Template, Context
def temp(request):
    t = Template('My name is {{ name }}.')
    c = Context({'name':'Pupbani'})
    return HR(t.render(c))

if/else - {% if %} {% endif %} 태그

  • 변수를 평가하고, 해당 변수가 True이면 시스템은 {%  if  %}{%  endif  %} 사이를 표시함
def condi1(request):
    html = """{% if num > 20 %} 
    <h1>참!</h1> 
    {% else %}
    <h1>거짓!</h1>
    {% endif %}"""
    t = Template(html)
    c = Context({'num':30})
    return HR(t.render(c))

  • {% elif %}를 사용해 여러개의 조건문을 만들 수 있음
def condi2(request):
    html = """{% if num < 10 %} 
    <h1>{{ num }}은 한자리 숫자</h1> 
    {% elif num >= 10 %}
    <h1>{{ num }}은 두자리 숫자</h1>
    {% endif %}"""
    t = Template(html)
    c = Context({'num':30})
    return HR(t.render(c))

 

 

for - {% for %} {% endfor %} 태그

  • 각 시퀀스의 각 항목을 반복할 수 있음
  • {% empty %}를 사용하면 해당 리스트가 비어있는 경우, 출력할 내용을 정의할 수 있음
  • 특수한 변수들
forloop.counter - 루프가 입력된 횟수(1부터)
- forloop.counter0 - 0부터 시작
forloop.revcounter - 루프의 나머지 항목 수(0 포함)
- forloop.revcounter0 - 0 제외
forloop.first - 루프가 처음일 경우 True
forloop.last - 루프가 마지막일 경우 True
forloop.parentloop - 부모 루프에 대한 forloop 객체에 대한 참조

 

def forloop(request):
    html = """{% for name in names%}
    <table border = 1>
    <tr><td>{{ forloop.counter }}</td>
    <td>{{ name }}</td></tr>
    </table>
    {% endfor %}"""
    t = Template(html)
    c = Context({'names':['Pupbani','Redbani','Yellbani']})
    return HR(t.render(c))

 

 

주석 - {# 주석 #} 태그

  • 주석 부분은 출력되지 않음
  • 주석 태그는 중첩되지 않음
def condi2(request):
    html = """{% if num < 10 %} 
    <h1>{{ num }}은 한자리 숫자{# 주석이용 #}</h1> 
    {% elif num >= 10 %}
    <h1>{{ num }}은 두자리 숫자{# 주석이용 #}</h1>
    {% endif %}"""
    t = Template(html)
    c = Context({'num':30})
    return HR(t.render(c))

 

템플릿 필터

  • 변수가 표시되기 전에 변수의 값을 변경하는 간단한 방법
  • 파이프( | ) 문자를 사용
 

django-filter — django-filter 22.1 documentation

© Copyright 2022, Alex Gaynor, Carlton Gibson and others. Revision 2c817681.

django-filter.readthedocs.io

def filter1(request):
    html = '<h1>{{ name|upper }}</h1>'
    t = Template(html)
    return HR(t.render(Context({'name':'pupbani'})))

 

HTML 파일을 가져와서 템플릿 사용

  • html 파일을 가져오려면 Django의 get_template() 함수를 사용
    • django.template.loader에 정의되 있음

  • settings.pyTEMPLATES를 확인해보기
    • BACKEND : 장고의 템플릿 백엔드 API를 구현하는 템플릿 엔진 클래스에 대한 점으로 구분된 파이썬 경로
    • DIRS : 기본적으로 비어있음, 엔진이 템플릿 소스 파일을 검색할 순서로 검색해야 하는 디렉터리 리스트를 정의
    • APP_DIRS : 엔진이 설치된 응용 프로그램 내에서 템플릿을 찾아야 하는지의 여부를 알려줌, 규약에 따라 True일 경우 장고 템플릿은 각 INSTALLED_APPS에서 "templates" 하위 디렉터를 찾음
    • OPTIONS : 백엔드 관련 설정 포함
# 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>Django</title>
</head>
<body>
    <h1>{{ name }}</h1>
    <table border="1">
        {% for i in strings %}
        <tr>    
            <th>{{ forloop.counter }}</th>
            <td>{{ i }}</td>
        </tr>
    {% endfor %}</table>
</body>
</html>
from django.http import HttpResponse as HR
from django.template import *
from django.template.loader import get_template
def hello(request): 
    t = get_template('index.html')
    contexts = {'name':'Pupbani','strings':['hello','good','bye']}
    return HR(t.render(contexts))

  • get_template을 사용하여 html을 불러오면 context를 사전 형태의 변수로 전달해야 함
    • Context 함수 사용 X

 

render()

  • 한줄의 코드로 모든 작업(HttpResponse, Template, Context)을 하기 위한 render()를 제공함
    • django.shortcuts 모듈에 정의

 

  • render(request, Template name , Context)
    • 첫번째 매개변수 - 요청
    • 두번째 매개변수 - 사용할 템플릿 이름
    • 세번째 매개변수 - Context, 인수 제공을 하지 않으면 빈 딕셔너리를 사용
from django.shortcuts import render
def hello(request): 
    contexts = {'name':'Pupbani','strings':['hello','good','bye']}
    return render(request,'index.html',contexts)

 

템플릿 내장/상속

  • {% include %}를 사용해 다른 템플릿의 내용을 포함할 수 있음
# include1.html
<div>
    <h1>Include Test</h1>
    <h2>템플릿 포함</h2>
</div>
#include.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>Django</title>
</head>
<body>
    <h1>템플릿 포함 테스트</h1>
    {% include "include1.html" %}
</body>
</html>
from django.http import HttpResponse as HR
from django.template.loader import get_template
def temp(request):
    t = get_template('include.html')
    contexts = {}
    return HR(t.render(contexts))

 

  • 템플릿 상속은 다음과 같은 과정을 수행함
    • html을 작성하고 {% block content %} {% endblock %} 사이의 부분을 자식에서 작성하도록 함
    • 자식 html은 {% extends "부모.html" %}를 사용해 상속을 표시하고 {% block content %} {% endblock %}로 구현을 함
# 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>Django</title>
</head>
<body>
    <h1>템플릿 상속</h1>
    <p>부모 html</p>
    {% block content %}
    <!-- 여기가 자식이 구현할 부분 -->>
    {% endblock %}
    <p>부모 html</p>
</body>
</html>
# parent.html
{% extends "base.html" %}
{% block content %}
<h1>자식 부분</h1>
<p>상속 완료</p>
{% endblock %}
from django.shortcuts import render
def inh(request):
    return render(request,'parent.html')

728x90
반응형

'Back-end & Server > Django' 카테고리의 다른 글

[Django] 폼(Form)  (0) 2023.01.20
[Django] Admin 사이트  (0) 2023.01.16
[Django] 모델  (0) 2023.01.16
[Django] 뷰와 URLconfs  (0) 2022.12.28
[Django] Django 시작하기  (0) 2022.12.28