티스토리 뷰

1. MTV 패턴

2. Django View

3. Django Template

4. Django Model


1. MTV 패턴

[그림 1] MTV 패턴

Django는 Model, Template, View 라는 MTV 패턴을 따르고 있는데, MTV는 MVC(Model, View, Controller)와 유사한 점이 많다. Django는 Controller의 역할을 Django Framework 자체에서 한다고 보고 있다. 따라서 MVC와 약간 다른 차이를 MTV로 설명하고 있다.

 

MTV에서 Model은 데이터를 표현하는데 사용되며, 하나의 모델 클래스는 DB에서 하나의 테이블로 표현된다. MTV의 View는 HTTP Request를 받아 그 결과인 HTTP Response를 리턴하는 컴포넌트로서, Model로부터 데이터를 읽거나 저장할 수 있으며, Template을 호출하여 데이터를 UI 상에 표현하도록 할 수 있다. MTV의 Template은 Presentation Logic 만을 갖는데 HTML을 생성하는 것을 목적으로 하는 컴포넌트이다.

 

 

2. Django View

Django에서 View는 다른 일반 MVC Framework에서 말하는 Controller와 비슷한 역할을 한다. 즉, View는 필요한 데이터를 모델에서 가져와서 적절히 가공한 후 웹 페이지 결과를 만들도록 컨트롤한다.

 

View들은 Django App 안의 views.py 라는 파일에 정의하게 되는데, 각 함수가 하나의 View를 정의한다. 각 View는 HTTP Request를 입력 파라미터로 받아들이고, HTTP Response를 리턴한다.

 

from django.http import HttpResponse

def index(request):
    return HttpResponse("<h1>Hello, World!</h1>")

 

위의 예제는 하나의 View 함수를 표현한 것이다. 이 함수는 입력으로 항상 request를 받아들이고, response를 리턴하게 된다. View는 웹페이지 내용을 갖는 HttpResponse 객체를 리턴하거나 Http404와 같은 Exception을 리턴한다. 여기서는 간단한 HTML Text를 포함한 HttpResponse() 객체를 리턴하고 있다. 일반적으로 Django에서는 좀 더 복잡한 HTML을 처리하기 위해 뷰 템플릿(Template)을 사용한다.

 

또 다른 예제로 return이 아닌 raise를 사용하여 Http404 Exception을 일으키는 것이 있다.

from django.http import Http404, HttpResponseNotFound

def error(request):
    #return HttpResponseNotFound('<h1>not found</h1>')
    raise Http404("Not Found")

비슷한 효과를 내기 위해 HttpResponseNotFound를 사용할 수 있지만, Http404가 좀 더 편리한 기능이다.

 

 

3. Django Template

Django에서 View가 MVC Framework의 Controller와 유사한 역할을 한다면, Django의 Template은 MVC Framework의 View와 비슷한 역할을 한다. Template은 View로부터 전달된 데이터를 템플릿에 적용하여 Dynamic한 웹 페이지를 만드는데 사용된다.

 

Template은 HTML 파일로서 Django App 디렉토리 밑에 "templates"라는 서브 디렉토리를 만들고 그 안에 템플릿 파일(*.html)을 생성한다. 이는 단일 App이거나 동일 템플릿명이 없는 경우 사용할 수 있다.

 

하지만, Django 개발 가이드라인은 "App디렉토리/templates/App명/템플릿파일"처럼 각 App 디렉토리 하위에 templates 서브 디렉토리를 만들고 다시 그 안에 App명을 사용하여 서브 디렉토리를 만든 후 템플릿 파일을 그 안에 넣기는 권장한다. (예: /home/templates/home/index.html)

 

이는 만약 복수의 App들이 동일한 이름의 템플릿을 가진 경우, View에서 잘못된 Template을 가져올 수 있기 때문이다. 예를 들어, App1에 create.html이 있고, App2에도 동일한 create.html 템플릿이 있는 경우, App2의 View에서 create.html를 지정하면, 처음 App1의 create.html을 사용하게 된다. 이는 템플릿을 찾을 때 자신의 App 내의 템플릿을 먼저 찾는 것이 아니라, 전체 App들의 템플릿 디렉토리들을 처음부터 순서대로 찾기 때문이다. View에서 "App2/create.html"과 같이 템플릿명을 지정하면 이런 혼동을 피할 수 있다.

 

템플릿을 순수하게 HTML로만 쓰여진 Static HTML 파일일 수도 있지만, 거의 대부분의 경우 View로부터 어떤 데이터를 전달받아 HTML 템플릿 안에 그 데이터를 동적으로 치환해서 사용한다. 예를 들어, 위의 index 뷰에서 message라는 데이터를 index.html이라는 템플릿에 전달하고 그 템플릿 안에서 이를 사용하기 위해서 다음과 같이 할 수 있다.

 

먼저 View (home/views.py)에서 다음과 같이 index()를 정의한다. 

from django.shortcuts import render

def index(request):
    msg = 'My Message'
    return render(request, 'index.html', {'message': msg})

여기서 render는 django.shortcuts 패키지에 있는 함수로 첫 번째 파라미터로 request를, 두 번째 파라미터로 템플릿을 받아들인다. 여기서 템플릿은 index.html로 지정되어 있는데, 이는 home/templates/index.html을 가리킨다. 세 번째 파라미터는 Iptional인데, View에서 템플릿에 전달한 데이터를 Dictionary로 전달한다. Dictionary의 Key는 템플릿에서 사용할 키(or 변수명)이고, Value는 전달하는 데이터의 내용을 담는다. 여기서는 message 라는 키로 "My Message"라는 문자열을 전달하고 있다.

 

만약 템플릿 파일을 home/templates/home/index.html 에 저장했다면, 위의 render() 문장을 아래와 같이 변경하면 된다.

def index(request):
    msg = 'My Message'
    return render(request, 'home/index.html', {'message': msg})

 

다음으로 Template (home/templates/index.html)에 HTML 문서를 작성한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{message}}</h1>
</body>
</html>

여기서 body 태그 안에 message를 보면 {{ }} 으로 둘러싸여 있는데, Django의 템플릿에서 {{ 변수명 }} 은 해당 변수의 값을 그 자리에 치환하라는 의미를 갖는다. Django Template은 또한 View로부터 전달된 다양한 데이터들을 템플릿에 편리하게 넣을 수 있도록 여러 템플릿 태그( {% %} 등)들을 제공하고 있다.

 

Django에서는 여러 템플릿 엔진을 선택하여 사용할 수 있으며, 이 셋팅은 Django 프로젝트의 settings.py 에서 할 수 있다. 디폴트 Django 템플릿 엔진을 사용하기 위해서는 settings.py 파일의 TEMPLATES 섹션에서 BACKEND를 django.template.backends.django.DjangoTemplates로 설정한다(기본으로 설정되어 있다).

 

Django 템플릿에서 사용하는 특별한 태그 및 문법을 Django 템플릿 언어 (Django Template Language)라 부른다. 템플릿 언어는 크게 템플릿 변수, 템플릿 태그, 템플릿 필터, 코멘트 등으로 나눌 수 있다.

 

템플릿 변수

<h4>
    Name : {{ name }}
    Type : {{ vip.key }}
</h4>

템플릿 변수는 {{ 와 }} 로 둘러싸여 있는 변수로서 그 변수의 값이 해당 위치에 치환된다. 변수에는 Primitive 데이터를 갖는 변수 혹은 객체의 속성 등을 넣을 수 있다.

 

템플릿 태그

{% if count > 0 %}
    Data Count = {{ count }}
{% else %}
    No Data
{% endif %}

{% for item in dataList %}
    <li>{{ item.name }}</li>
{% endfor %}

{% csrf_token %}

템플릿 태그는 {% 와 %}로 둘러싸여 있는데, 이 태그 안에는 if, for 루프와 같은 Flow Control 문장에서부터 웹 컨트롤처럼 내부 처리 결과를 직접 덤프하는 등 여러 용도로 쓰일 수 있다. 위의 처음 부분은 if와 for 태그를 사용한 예이고, 마지막은 CSRF 해킹 공격에 대응하여 토큰을 넣어주는 csrf_token 태그를 사용한 예이다.

 

템플릿 필터

날짜 포맷 지정
{{ createDate|date:"Y-m-d" }}

소문자로 변경
{{ lastName|lower }}

템플릿 필터는 변수의 값을 특정한 포맷으로 변형하는 기능을 한다. 예를 들어, 날짜를 특정 날짜 포맷으로 변경하거나 문자열을 대소문자로 변경하는 일을 할 수 있다.

 

코멘트

{# 1라인 코멘트 #}

{% comment %}
    <div>
        <p>
            불필요한 블럭
        </p>
        <span></span>
    </div>
{% endcomment %}

템플릿에서 코멘트를 넣는 방법은 크게 2가지이다. 한 라인에 코멘트를 적용할 때에는 코멘트를 {# 과 #} 로 둘러싸면 된다. 또한, 복수 라인 문장을 코멘트할 경우는 문장들을 {% comment %} 태그와 {% endcomment %} 로 둘러싸면 된다.

 

HTML Escape

HTML 내용 중에 <, >, ', ", & 등과 같은 문자들이 있을 경우 이를 그 문자에 상응하는 HTML Entity로 변환해 주어야 하는데, Django 템플릿에서 이러한 작업을 자동으로 처리해 주기 위해 {% autoescape on %} 탬플릿 태그나 escape 라는 필터를 사용한다.

{% autoescape on %}    # autoescape 태그
    {{ content }}
{% endautoescape %}

{{ content|escape }}    # escape 필터

예를 들어, 위 예제에서 content 라는 변수에 인용부호가 들어 있다고 할 때, autoescape 태그나 escape 필터를 사용해서 자동으로 변환하게 할 수 있다. 만약 이러한 변환을 하지 않으면 HTML이 중간에 깨지게 된다.

 

4. Django Model

Django에서 Model은 데이터 서비스를 제공하는 Layer이다. Django의 Model은 각 Django App안에 기본적으로 생성되는 models.py 모듈 안에 정의하게 된다. models.py 모듈 안에 하나 이상의 모델 클래스를 정의할 수 있으며, 하나의 모델 클래스는 데이터베이스에서 하나의 테이블에 해당된다.

 

Django 모델에 대해 알아보기 위해 아래 그림과 같이 feedback이라는 새 Django App을 생성하였다. 이어 feedback App 디렉토리 안에 있는 models.py 파일에 새로운 모델 클래스(Feedback)을 추가하였다.

'Django' 카테고리의 다른 글

[Django] App 사용 방법  (0) 2022.10.24
[Django] 개발 환경 구축  (0) 2022.10.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함