Develop/Django

[Django][파이썬 웹 프로그래밍] 04. Django의 핵심 기능 (2)

dawonny 2021. 7. 21. 23:20
728x90
반응형

이 글은 [파이썬 웹 프로그래밍](저자 김석훈, 출판사 한빛미디어) 교재를 보고 공부하며 정리한 글임.


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) < 문자는 &lt; 로 변경하고 & 문자는 &amp; 로 변경

 

 

<이 자동 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>

필드들의 필드 타입에 따라서 어떻게 변환 되었는지 확인하자.

 

728x90
반응형