Django 템플릿 시스템은 템플릿 문법으로 작성된 템플릿 코드를 해석해 템플릿 파일로 결과물을 만들어준다. 템플릿 코드를 템플릿 파일로 해석하는 과정을 장고에서 '렌더링' 이라고 부른다.
템플릿 변수
템플릿 코드에서 변수를 사용할 수 있다. 변수는 아래와 같은 형식을 사용한다.
{{ variable }}
변수 속성에 접근하기 위해서 '.' 연산자가 있는데 이 연산자 해석은 아래와 같다.
- Dictionary타입인지 확인한다. 딕셔너리 타입인 경우 key값으로 해석한다
- 변수의 속성을 찾는다. 있다면 해당 변수의 속성으로 해석한다
- 리스트 속성인지 확인한다. 리스트 속성이면 인덱싱을 한다
위 세가지 모두 아닌경우 빈 문자열로 반환한다. 만약 이 반환되는 문자열을 바꾸고 싶다면 settings.py의 TEMPLATES의 OPTIONS에 string_if_invalid필드를 추가해 주면 된다.
// settings.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',
],
'string_if_invalid': 'Something went Wrong', # 이 부분
},
},
]
아래 사진을 보면 views.py의 index에서 context내에 a라는 값은 int타입이다. 그렇기 때문에 속성도, 리스트도 딕셔너리도 아니다. 그렇기 때문에 아까 settings.py에서 설정해준대로 디폴트 값이 빈 문자열이 아닌 지정한 문자열이 출력되는것을 볼 수 있다.
https://docs.djangoproject.com/en/1.8/ref/templates/api/#invalid-template-variables
템플릿 필터
필터란 일반적으로 객체, 혹은 처리 결과에 추가 명령을 적용해 명령에 맞게 최종 결과를 반환하는것을 말한다. 템플릿 변수에 필터를 적용하여 변수 출력 결과를 변경할 수 있다
필터는 '|'(역슬래시랑 같이있다)를 사용한다.
< lower >
모든 문자를 소문자로 만들어준다.
{{ var | lower }}
< join >
리스트의 .join문법과 동일하다.
{{ list | join:"/" }}
< default >
value변수값이 False 혹은 없는 경우에는 지정한 값으로 변경할 수 있다. 템플릿 변수의 '.' 속성에 대해 빈 문자열을 반환한 경우와 연계해 사용할 수 있을것 같다라는 생각이 든다.(TEMPLATE_STRING_IF_INVALID 가 있지만 상황에 맞게 문자열을 반환하고 싶은 경우)
{{ var | default:"nothing" }}
< pluralize >
변수값이 1개가 아닌 여러개일때 복수 접미사 s를 붙여준다(s가 디폴트). es 혹은 ies를 붙이고 싶은 경우 필터에 인자를 사용해준다
{{ var|pluralize}} # s를 붙인다
{{ var|pluralize:"es}} # es를 붙인다
{{ var|pluralize:"ies"}} # ies를 붙인다
이외 필터에 대한것은 아래 Document를 참고하자
https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#ref-templates-builtins-filters
또한 이 필터는 custom하여 만들 수 있다. 아래 내용을 참고하자
< 템플릿 태그 >
< for 태그 >
{% for %} ~ {% endfor %} 로 묶어준다.for태그에서 사용되는 변수들은 아래와 같은것들이 있다.
forloop.counter | 현재까지 루프를 실행한 카운터, 1부터 시작 |
forloop.counter0 | 위와 동일하나 0부터 시작 |
forloop.revcounter | 루프 끝에서 현재까지 몇번째인지 카운트한다, 1부터 시작 |
forloop.revcounter0 | 위와 동일하나 0부터 시작 |
forloop.first | 루프 첫번째 실행이면 True를 가진다 |
forloop.last | 루프 마지막 실행이면 True를 가진다 |
forloop.parentloop | 중첩 루프에서 현재 루프의 바로 윗 루프를 의미한다. |
<ul>
{% for q in question_id %}
<li><a href="/polls/{{ q.id }}">{{ q.question_text }}</a></li>
{% endfor %}
</ul>
< if 태그 >
{% if %} ~ {% elif %} ~ {% else %} ~ {% endif %} 형태이다. 일반적인 if 문과 논리는 동일하다.
{% if question_id %}
<ul>
{% for q in question_id %}
<li><a href="/polls/{{ q.id }}">{{ q.question_text }}</a></li>
{% endfor %}
</ul>
<h1>{{ a.q }}</h1>
{% else %}
<p>No polls are available</p>
<h1>{{ a.q }}</h1>
{% endif %}
< csrf token 태그 >
POST방식 <form>을 사용하는 템플릿 코드에서 CSRF(Cross Site Request Fogery)공격을 방지하기 위한 태그이다. {% csrf_token %} 형태이며, <form>엘리먼트의 첫줄 다음에 넣어주면 된다.
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for i in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ i.id }}">
<label for="choice{{ forloop.counter }}">{{ i.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>
< url 태그 >
{% url %}태그도 자주 사용한다. 이는 URL하드 코딩을 방지하기 위한 것이다. 예를 들어 "polls/3/vote/"와 같이 URL을 적는것을 의미한다. 이의 문제점은 모든 html문서를 찾아서 변경해야한다는 문제점이발생하며, 혹여나 URL에 Query Param이 있는 경우에도 그때 그때 변수 처리를 해주어야 하므로 하드코딩 하는것은 좋은 방법이 아니다. {% url %}태그는 아래와 같은 형태로 작성한다.
{% url 'namespace:view-name' args1 args2 ... %}
<li><a href=" {% url 'polls:detail' q.id %}">{{ q.question_text }}</a></li>
<a href="{% url 'polls:detail' question.id %}">Vote again?</a>
< with 태그 >
{% with %} 태그는 아래와 같이 특정 변수에 저장해 두는 기능을 한다.
{% with total=q.question_text %}
<p>Question : {{ total }}</p>
{% endwith %}
with옆에 저장할 변수들을 입력하면 되며, 주의할 점은 대입연산자와 변수명, 대입식을 모두 붙여써야한다.(total=q.question_text) with문에 저장된 변수의 수명은 {% with %} ~ {% endwith %} 까지이다.
이외 다른 태그들은 Document를 참고해보자(built in tags)
https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#ref-templates-builtins-tags
템플릿 주석
템플릿 코드에도 주석이 있다.
< 한줄 주석 >
한줄 주석을 위해서는 아래와 같이 {# #}로 묶어서 표현한다.
{# comment here #}
<여러줄 주석>
여러줄 주석은 {% comment %} ~ {% endcomment %}태그를 사용해 주면 된다.
{% comment %}
multiline
comment here
{% endcomment%}
'Back-End > Python Django' 카테고리의 다른 글
[Django] form클래스로 폼 생성하기 (0) | 2022.02.22 |
---|---|
[Django] 템플릿 상속하기 (0) | 2022.02.22 |
[Django][django shell] 장고 파이썬 쉘로 데이터 조작하기 (0) | 2022.02.18 |
[Django] [admin page] 장고 어드민 페이지 title 변경하기 (0) | 2022.02.18 |
[Django] [admin page]search_fields (0) | 2022.02.18 |