본문 바로가기

TIL

[TIL 2024. 04. 09] MTV Pattern | DTL 문법 | 상속

MTV Pattern

파이썬 웹 프레임워크인 장고(Django)에서 사용된 '디자인 패턴'은 'MTV 패턴'이다.

MTV 패턴은 기존의 MVC패턴을 살짝 변형한 것이므로, MVC에 대해서 명확히 알고 가는게 좋다

 

MVC는 Model, View, Controller의 3파트로 구성되어 있다.

이 패턴은 하나의 큰 소프트웨어를 부분으로 나눠서 생각해보기 위해 등장했다. 이렇게 큰 하나의 소프트웨어를 부분으로 나눠서 생각하면 다음과 같은 장점이 있다.

  • 개발의 생산성 증가: 다수가 각 기능을 분담할 수 있으므로 동시에 독립적으로 각 부분을 개발할 수 있다
  • 유지보수가 용이함: 문제가 생길 시 해당 부분만 디버기하면 된다
MVC
Model: 데이터 관련 처리
View: 레이아웃 관련 처리 (보이는 것)
Controller: Model과 View를 연결하는 로직 처리, 메인 비지니스 로직 담

 

 

장고의 MTV패턴은 사실상 MVC패턴과 용어만 다를 뿐, 본질은 거의 똑같다.

MVC MTV
Model Model
View Template
Controller View

 


클라이언트의 request시: 처리 흐름도

 

 

즉, 처리과정을 정리해보면 다음과 같다

 

1. http에서 요청을 보냄 (-> HttpRequest 객체 형성)

  •  HttpRequest 형성: request..GET.get('key')와 관련됨
    • HttpRequest는 class의 instance(객체)임
    • bold부분은 장고가 자체적으로 지원, 밑줄 부분은 파이썬 기본 문법
    • GET은 '쿼리스트링' 형태로 데이터를 처리하므로, request.GET은 장고가 쿼리스트링을 마치 '딕셔너리'처럼 처리할 수 있게 해주는 부분임
    • get.('key')는 파이썬 기본문법에 해당한다
my_dict = { 'a':1}

my_dict['a']
my_dict.get('a')
my_dict.get('b', 9)

print(my_dict['a'])
print(my_dict.get('a'))
print(my_dict.get('b', 9))

#1
#1
#9

 

실제로는 my_dict.get('a')의 형태도 많이 사용된다. 그  이유는 에러 발생을 방지할 수 있기 때문이다. 다시 말해, my_dict.get('a')의 형태 의 형태는 dict에 해당 key값이 없는 경우에도(key값이 'b'일 때) 디폴트값을 부여해서 에러를 방지할 수 있다.

 


2. urls.py (url 처리)

 

urls.py에서 요청이 들어온 해당 url경로(path)를 확인하고, 그에 맞는 view로 요청을 넘겨준다.

  • urls.py는 프로젝트 디렉토리에 위치하고, views.py는 앱 디렉토리에 위치하므로 반드시 import를 해줘야 한다.
from <앱 이름> import views

 


 

3. views.py (view 처리)

 

views.py는 해당 요청이 데이터 관련이라고 판단하면 Models.py와 주고받고, 레이아웃 관련 요청이라면 template(html)과 요청을 주고 받아서 데이터를 가져온 뒤 그것들을 잘 버무려서 HttpResponse를 클라이언트에게 반환한다. 즉, HttpResponse의 주체가 views.py이다. 

 

장고 기초 강의에서는 '함수형 뷰'에 대해서 다루고 있으므로 views.py에서는 일반적으로 함수(혹은 클래스)를 정의한다.

(추후 장고 심화 강의에서 '클래스형 뷰'를 다룰 예정!)

 

이때 각 함수는 매개변수로 'request'를 받는다. 즉, 다시 말해 받아온 request (엄밀히는 HttpRequest)를 view함수의 첫번째 인자로 준다.

 


DTL문법

DTL이란 Django Template Language의 줄임말이다.

 

파이썬 웹 프레임워크(장고)를 사용하는 개발자라면 파이썬이 익숙할 것이라는 전제하에 파이썬과 비슷하게 만든 장고의 template에서만 사용가능한 문법이다. 

 

단, 주의할 점은 DTL과 파이썬 코드 자체는 별개이므로, 장고의 template(html)에서 파이썬 코드를 작성해도 당연히 동작하지 않는다는 것이다.

 

DTL문법에서 제일 중요한 순서로 꼽으라고 하면 변수, 태그 > 필터 > 주석 일 것이다.

따라서, 학습의 우선순위도 '변수'와 '태그'가 가장 높다.

 

  • 변수 (Variable)
    • views.py의 view함수에서 'context(=dict)'로 넘긴 데이터에 접근하기 위해 사용
    • context가 dict이므로 당연히 'key'값을 사용
    • '.'을 사용
    • 기본형태: {{ variable }}
#views.py
def hello(request):
    name = 'Amy'
    tags = ['python', 'django', 'html', 'css', 'javascript']
    books = ['세이노의 가르침', '해변의 카프카', '향수', '헨젤과 그레텔']
    contents = ['파묘', '서울의 봄', '남산의 부장들', '변호인', '굿 플레이스']
    context = {
        'name': name,
        'tags': tags,
        'books': books,
        'contents': contents
    }
    return render(request, 'hello.html', context)

 

#html
{% block content %}
<h1>Hello, {{ name }}</h1>
<p>모든 태그: {{ tags|join:", " }}</p>
<p>오늘의 태그: {{ tags.1|upper }} (글자수: {{ tags.1|length }})</p>
<p>내 책 목록</p>
<ul>
    {% for book in books %}
    <li>{{ book }}</li>
    {% endfor %}
</ul>
<p>내 컨텐츠 목록</p>
<ul>
    {% for content in contents %}
    <li>{{ content }}</li>
    {% endfor %}
</ul>

 

  • 태그 (Tags)
    • 반복문, 조건문 등 제어흐름 형성을 위해 사용함
    • 일부 태그는 시작태그와 종료태그가 있음 -> django 공식문서에서 확인 가능
    • 기본 형태: {% tag %}

 

  • 필터 (Filters)
    • 데이터 자체에는 변화가 없고, 단지 데이터를 표현하는 방식을 바꿀 때 사용함
    • 일부 필터는 인자를 받음 ->  django 공식문서에서 확인 가능
    • 기본 형태: {{ variable|filter }}

 


상속

html 자동 완성시 생성되는 부분처럼 모든 html에 공통되는 부분은 모으고, 수정 가능한 'block'을 넣어서 'base.html'과 같은 상위 template을 생성한다.

 

그리고 이 base.html을 상속해서 활용하면 코드의 재사용성은 물론 각 html의 코드도 무척 간결해진다. 

 

단, 상속하겠다는 뜻을 밝히는 extends문은 html의 가장 위에 위치해야 한다.

#html
{% extends 'base.html' %}

{% block content %}	#content는 <block명>
#body내용
{% endblock content %}

 

또 주의해야 할 점은 base.html은 구조상 app디렉토리와 동일선상에서 'templates'디렉토리를 별도로 만들어서 넣어줘야 한다. 그리고 이 디렉토리를 장고가 찾을 수 있도록 settings.py에서 명시해줘야 한다.

 

settings.py에 꼭 명시해야 하는 사항들
1. app 등록: INSTALLED APP
2. base.html이 있는 templates디렉토리: TEMPLATES의 DIRS에 명시
'DIRS': [BASE_DIR / 'templates'],​


여기서 BASE_DIR이란 BASE DIRECTORY를 말하며, 현재 있는 settings.py파일의 parent의 parent를 말한다.
즉, 프로젝트 디렉토리 내에서 app디렉토리, inner 프로젝트 디렉토리와 동일선상을 말한다.