티스토리 뷰
Fat Model
Stupid Template :
Thin View
Template Engines 몇 가지
Django Template Engine : Django 기본 지원 템플릿 엔진
• Jinja2 : 써드파티 엔진이었으나, 최근에 최소한의 지원이 내장됨.
• Django Template Engine과 문법이 유사
• 장고 프로젝트에 쓸려면 django-jinja 추천
• Mako, HamlPy
장고 프로젝트에서 다른 템플릿 엔진을 쓸 수도 있으나, 가급적이면 기본 장고 템플릿 엔진에 먼저 익숙해지기를 권장
Django Template Engine Syntax
{% extends "base.html" %} # extends = tag / "base.html" = 인자 (중요) 탬플릿 태그에서는 인자로 넘기는 ( ) 와 , 를 사용하지 않음 {# 파이썬 로직 불가. 템플릿 렌더링 전에 필요한 값을 인자로 받습니다. #} {% for row in rows %} <tr> {% for name in row %} <td>{{ name }}</td> {% endfor %} </tr> {% endfor %} |
## 파이썬 문법과 비교 # Positional Arguments def mysum(x,y): return x+y
mysum(1,2) # 위치에 기반하여 첫번째, 두번쨰 인자 대입 # Keyword Arguments def mysum(x,y,z=0): return x + y + z
mysum(1,2,z=10) |
Variables
- {{ first_name }}
- {{ mydict.key }} : dict의 key에 attr처럼 접근
- {{ myobj.attr }}
- {{ myobj.func }} : 함수호출도 attr처럼 접근. 인자있는 함수호출 불가
- {{ mylist.0 }} : 인덱스 접근도 attr처럼 접근
class Person: def say_hello(self): print("hello") person = Person() people = {'Tom' : 10, 'Steve' : 20} names = ['Tom', 'Steve'] # python code people['Tom'] person.say_hello names[0] # django templates engine {{ people.Tom }} {{ person.say_hello }} {{ names.0 }} |
Django Template Tag
- Django Templates 용 함수
- {% %} 홀로 쓰이기도 하며, 2개 이상이 조합되기도 함.
- 빌트인 Tag가 지원되며, 장고앱 별로 커스텀 Tag 추가 가능
- block, comment, csrf_token, extends, for, for ... empty, if, ifchanged, include, load, lorem, now, url, verbatim, with 등
1. block tag
• 템플릿 상속에서 사용
• 자식 템플릿이 오버라이딩할 block 영역을 정의
• 자식 템플릿은 부모가 정의한 block에 한해서 재정의만 가능. 그 외는 모두 무시
{% block block-name %}
block 내에 내용 사용
{% endblock %}
2. comment tag (중요) 서버 단에서 처리를 무시함으로, front단에서 확인 되지않음
• 템플릿 주석
• comment 영역을 서버 단에서 처리하지 않음. JavaScript 주석과 햇갈림 주의
{% comment "Optional note" %} # 코멘트 설명 추가 (생략 가능)
이 부분은 렌더링되지 않습니다.
{% endcomment %}
# python code 주석 # 주석 1 ''' 주석1 주석2 주석3 ''' # django templates {# 주석1 #} {% commnet '이곳은 주석입니다. %} 주석1 주석2 주석3 {% endcomment %} |
csrf_token tag
• Cross Site Request Forgeries를 막기 위해 CSRF Middleware가제공
이는 HTML Form의 POST요청에서 CSRF토큰을 체크하며, 이때CSRF토큰이 필요
• csrf_token tag를 통해 CSRF토큰을 발급받을 수 있다.
<form method="POST" action=""> {% csrf_token %} <input type="text" name="author" /> <textarea name="message"></textarea> <input type="submit" /> </form> # 프로젝트/settings.py MIDDLEWARE = [ .... 'django.middleware.csrf.CsrfViewMiddleware', ] |
get요청 시 form 형식의 포맷을 받을 때 토큰 발급 받고 데이터 입력 후 post처리 시 발급된 토큰과 비교하여 서버 내부에서 처리
extends tag
• 자식 템플릿에서 부모 템플릿 상속을 명시
• extends tag는 항상 템플릿의 처음에 위치
• 상속받은 자식 템플릿은 부모 템플릿에서 정의한 block만 재정의할 수있다.
{% extends "base.html" %}
for tag
• 지정 객체를 순회
• 파이썬의 for문과 동일
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
loop내 추가 지원 Variable
• forloop.counter : 반복 인덱스 (1부터 시작하여 1씩 증가)
• forloop.counter0 : 반복 인덱스 (0부터 시작하여 1씩 증가)
• forloop.revcounter : 반복 인덱스 (끝인덱스부터 시작, 1씩 감소)
• forloop.revcounter0 : 반복 인덱스 (끝인덱스-1부터 시작, 1씩 감소)
• forloop.first, forloop.last : 첫 실행 여부, 마지막 실행 여부
• forloop.parentloop : 중첩 loop에서 부모 loop를 지정
for ... empty (유용하게 사용됨!)
• for tag 내에서 지정 object를 찾을 수 없거나, 비었을 때 empty block이 수행
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% empty %} #빈 리스트가 존재 하였을 경우 아래 내용 출력
<li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>
# python code non_list = [] if non_list: for non in non_list: print(non_list.name) else: print("empty") # django templates code {% for non in non_list %} ##추천 {{ non_list.name }} {% empty %} <li> empty </li> {% endfor %} {% if non_list %} {% for non in non_list %} {{ non.name }} {% endfor %} {% else %} empty {% endif %} |
if tag
• 파이썬의 if문과 동일
{% if athlete_list %}
Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
Athletes should be out of the locker room soon!
{% else %}
No athletes.
{% endif %}
if changed
• 변수가 지정되지 않으면, content의 내용이 변경되었을 때 True 판정
• 변수가 지정되면, 지정 변수값 변경이 되었을 때 True 판정
<h1>Archive for {{ year }}</h1>
{% for date in days %}
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
{% endfor %}
{% for date in days %}
{% ifchanged date.date %}
{{ date.date }}
{% endifchanged %}
{% ifchanged date.hour date.date %}
{{ date.hour }}
{% endifchanged %}
{% endfor %}
include tag
• 다른 템플릿을 로딩/렌더링을 수행하며, 현재 context가 그대로 전달
• include 시에 keyword 인자를 지정하여, 추가 context 지정 가능
{% include "foo/bar.html" %}
{% include "name_snippet.html" with person="Jane" greeting="Hello" %}
load tag # python import 와 동일 함
• 커스텀 Template Tag/Filter Set 로딩
• load 시에 다수 팩키지 기입 가능
{% load custom_tags1 package.other_tags2 %} ## 인자를 지정할때 () , 가 없다. import os.path ; os.path.join
• load 시에 library내 특정 filter/tag 선택적 로딩 기능
{% load foo bar from custom_tags1 %} ## from os.path import join ; join
lorem tag # 랜덤 문자열을 출력해 데이터를 채워 넣음
• 랜덤 채우기 텍스트를 생성
{% lorem [count] [method] [random] %} # [] 생략 가능
• count : 생성할 단락/단어의 수 (디폴트 : 1)
• method : 단어일 경우 w 지정, HTML 단락일 경우 p 지정, Plain Text 단락일 경우 b 지정 (디폴트: b)
• random : random 지정/미지정, 지정 시에는 보통의 채우기 텍스트 ("Lorem ipsum dolor sit amet ...")를 쓰지 않고, 랜덤 문자열 생성
Examples
{% lorem %} : 보통의 채우기 텍스트 출력
{% lorem 3 p %} : HTML 단락 3개 출력
{% lorem 2 w random %} : 랜덤 단어 2개 출력
> 컨텐츠를 채워넣어서 전체 템플릿 마크업
now tag
• 현재 날짜/시각을 출력
• 출력포맷은 date templatetag 참고
It is {% now "jS F Y H:i" %}
url tag
• URL Reverse를 수행한 URL문자열을 출력
• 인자처리는 django.shortcuts.resolve_url 함수와 유사하게 처리하나, get_absolute_url 처리는 하지 않음. # 실제 reverse가 사용됨
{% url "some-url-name-1" %}
{% url "some-url-name-2" arg arg2 %}
{% url "some-url-name-2" arg arg2 as the_url %}
verbatim tag #AngularJS
• 지정 블락 내에서는 장고 템플릿 엔진을 통한 렌더링을 수행하지 않음.
• 대개 자바스크립트에서 {{ }} 를 쓸 수 있도록 하기 위한 목적
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
• AngularJS는 장고템플릿엔진과 동일한 interpolation symbol 을 쓰기 때문에 충돌 발생.
• 방안1) 장고 측에서 verbotim tag 를 통해 angularjs에서 쓸 수 있도록 영역을 보장
• 방안2) angularjs 측에서 interpolation symbol을 변경
{% verbatim %}
<div ng-app=""> <p>Name: <input type="text" ng-model="name"></p> <p>You wrote: {{ name }}</p> <!-- verbatim을 쓰지 않으면, 이 부분을 django에서 먼저 처리해버림. --> </div> |
{% endverbatim %}
with tag
• 변수에 새로운 값을 assign
{% with alpha=1 beta=2 %}
...
{% endwith %}
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
"""본 내용은 AskDjango VOD, "장고 차근차근 시작하기" 강의내용을 참고하여 작성했습니다.(https://nomade.kr/)"""
'Python > * Django' 카테고리의 다른 글
15. HTML Form (0) | 2017.12.15 |
---|---|
14. Django 템플릿 엔진 - 템플릿 필터 (0) | 2017.12.15 |
12. URL Reverse (0) | 2017.12.13 |
11. Django Template Loader (0) | 2017.12.13 |
10. Django 템플릿 상속 (0) | 2017.12.13 |