[Django][파이썬 웹 프로그래밍] 04. Django의 핵심 기능 (2)
이 글은 [파이썬 웹 프로그래밍](저자 김석훈, 출판사 한빛미디어) 교재를 보고 공부하며 정리한 글임.
4.3 템플릿 시스템
템플릿 시스템 : MVT 방식에서 UI 를 담당하는 기능
4.3.1 템플릿 변수
형식)
{{ variable }}
정의가 되어 있지 않은 변수 사용하면 빈 문자열 ' '로 채워주고
이걸 변경하고 싶으면 setting.py에서 TEMPLATE_STIRNG_IF_IINVALID 속성을 지정해주면 된다.
4.3.2 템플릿 필터
템플릿 변수에 필터를 적용해서 변수의 출력결과를 변경하려면 파이프 문자 | 를 사용하자
{{ name|lower }}
-> name 변수값의 문자들을 소문자로 바꿔주는 필터
{{ text|escape|linebreaks }}
->text 변수값 중에서 특수문자를 escape 해주고 그 결과 문자열에 HTML <p> 태그 붙이기 (행바꿈 할때 많이 사용)
{{ bio|truncatewords:30 }}
-> bio 변수값 중 앞에 30개 단어만 보여주고 줄바꿈 문자는 없애줌
{{ list|join:" // " }}
-> 인자들을 // 를 넣어서 묶어줌. 'a' ,'b', 'c' 였으면 'a // b // c'로
{{ value|default:"nothing" }}
-> 변수 값이 False거나 없으면 nothing으로 보여준다.
{{ value|length }}
-> 변수값의 길이를 반환, 변수는 리스트여도 된다
{{ value|stringtags }}
-> 변수값에서 html 태그 모두 없애줌
{{ value|pluralize }}
-> 복수접미사 필터
{{ value|pluralize:"es" }} 또는 {{ value|pluralize:"ies" }}
-> es나 ies 복수 접미사 붙일때 사용
{{ value|add:"2" }}
->더하기 필터(여기선 2를 더해줌)
{{first|add:second }}
->문자열을 더해주거나 리스트끼리 더해주기도함. 정수끼리 더해주기도 가능. 실패하면 빈 문자열 반환
4.3.3 템플릿 태그
{% tag %} 의 형식을 가짐
{% for %}나 {% if %} 많이 씀
{% for %} 태그
ex)
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
for 태그에 사용되는 변수
- forloop.counter
- forloop.counter()
- forloop.revcounter
- forloop.first
- forloop.last
- forloop.parentloop
{% if %} 태그
ex)
{% if athlete_list %}
Number of ahthletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
Athletes should be out of the locker room soon!
{% else %}
No athletes.
{% endif %}
{% csrf_token %} 태그
ex)
<form action="." method="post">{ %csrf_token %}
POST 방식 <form> 사용하는 템플릿코드에선 이 태그를 사용해야 한다. (CSRF 공격 방지 위함)
<form> 엘리먼트 첫줄 다음에 넣어주자
{% url %} 태그
형식
{% url 'namespace:view-name' arg1 arg2 %}
-> namespace = urls.py 파일의 include() 함수나 app_name 변수에 정의한 namespace 이름
view-name = urls.py 파일에서 정의한 URL 패턴 이름
argN = 뷰 함수에서 사용하는 인자. 없을수도있음
{% with %} 태그
ex)
{% with total = business.employees.count %}
{{ total }} people works at business
{% endwith %}
특정 값을 변수에 저장하는 기능
{% load %} 태그
ex)
{% load somelibrary package.otherlibrary %}
(개발자라 필요에 따라 스스로 만든 )사용자 정의 태그 및 필터를 로딩해줌.(사용전에 로딩해야함)
4.3.4 템플릿 주석
한 줄로 주석 쓸 때
{# #}
여러 줄로 주석 쓸 때
{% comment %} 태그
4.3.5 HTML 이스케이프
장고에는 자동 이스케이프 기능이 있다.
ex) < 문자는 < 로 변경하고 & 문자는 & 로 변경
<이 자동 HTML 이스케이프 기능을 비활성화 시켜야 하는 경우>
- HTML 태그 그대로 출력하고 싶다
- 이스케이프 문자 들어있는 이메일 메세지를 템플릿 파일에 출력
<이스케이프 비활성화 하는 방법>
- safe 필터 사용하기
- {% autoescape %} 태그 사용하기 ex){% autoescape off %} {% endautoescape %}
4.3.6 템플릿 상속
템플릿 상속 -> 템플릿 코드 재사용, 일관성 높이기
{% block %} 태그를 통해 하위로 상속해줄 부분 지정
{% extends %} 태그 사용해서 상속받는다는 것을 표시
4.4 폼 처리하기
4.4.1 HTML 에서의 폼
폼 -> 사용자로부터 입력을 받기 위해 사용, 입력한 데이터는 서버로 보내진다.
폼은 <input> 말고도 action(어디로 보낼지 지정) 속성과 method(어떤 HTTP 메소드로 보낼지 지정) 속성을 설정해주어야 함
HTTP 프로토콜 폼에서 사용할 수 있는 HTTP 메소드는 GET, POST
검색 폼에는 GET 방식이 적절하고
데이터베이스 내용 변경하는 요청은 POST 방식
4.4.2 장고의 폼 기능
4.4.3 폼 클래스로 폼 생성
폼도 클래스로 정의해서 간편하게 만들 수 있다.
사용자의 이름을 입력 받는 간단한 폼을 만든다고 해보자.
최종적인 템플릿은 다음과 같다
<form action="/your-name/" method="post">
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current name }}">
<input type="submit" value="OK">
</form>
post 방식으로 폼 데이터를 /your-name/ 으로 보내달라고 요청 (/your-name/에 해당하는 뷰가 있음)
이런 <form> 엘리먼트의 기능 제공을 위해 폼 클래스를 정의한다.
모든 폼 클래스는 django.forms.Form 의 자식클래스로 정의됨
아래는 필드가 your_name 하나인 폼 클래스이다.
from django import forms
calss Nameform(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
이 폼 클래스가 렌더링 되면 다음과 같이 됨
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100">
이 렌더링 결과에 <form> 태그나 submit 버튼은 없음 -> 직접 템플릿에 넣어줘야함
아래는 name.html
<form action="/your-name/" method="post">
{% csrf_token %}} #CSRF 공격 방지
{{ form }}
<input type="submit" value="Submit" />
</form>
4.4.4 뷰에서 폼 클래스 처리
폼을 처리하는 뷰는 2개가 필요.
- 폼을 보여주는 뷰
- 제출된 폼을 처리하는 뷰 -> 장고는 하나의 뷰로 통합하여 폼을 처리
뷰가 GET 방식으로 요청 받은 경우 : 사용자에게 처음으로 폼을 보여주도록 처리
뷰가 POST 방식으로 요청 받은 경우 : 데이터가 담긴 제출된 폼으로 간주하여 처리하게 됨
4.4.5 폼 클래스를 템플릿으로 변환
폼 클래스를 렌더링 하여 html 템플릿으로 변환
{{ form }} 구문은 HTML의 <label> 과 <input> 엘리먼트 쌍으로 렌더링 됨
{{ form }} 외에도 3가지 옵션이 있다
- {{ form.as_table }} : <tr>태그로 감싸서 테이블 셀로 렌더링됨. {{ form }}과 동일
- {{ form.as_p }} : <p>태그로 감싸도록 렌더링됨
- {{ form.as_ul }} : <li>태그로 감싸도록 렌더링 됨
<p>태그로 렌더링 된 코드 예시를 보자
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
위와 같은 폼 클래스가 있다면 {{ form.as_p }} 옵션으로 변환
<p><label for="id_subject">Subject:</label>
<input id="id_subject" type="text" name="subject" maxlength="100" /></p>
<p><label for="id_message">Message:</label>
<input type="text" name="message" id="id_message" /></p>
<p><label for="id_sender">Sender:</label>
<input type="email" name="sender" id="id_sender" /></p>
<p><label for="id_cc_myself">Cc myself:</label>
<input type="checkbox" name="cc_myself" id="id_cc_myself"/></p>
필드들의 필드 타입에 따라서 어떻게 변환 되었는지 확인하자.