[Django/장고] MVT 패턴이란
웹 프로그램 개발 시 일반적으로 언급되는 MVC 패턴에 대한 소개는 이전 포스팅에서 했었다.
2019/06/11 - [분류 전체보기] - MVC 패턴이란
MVT 패턴이란
장고 프레임워크에서는 View를 Template, Controller는 View라고 표현하며, MVC를 MVT 패턴이라고 한다. 모델은 데이터 베이스에 저장되는 데이터를 의미하는 것이고, 템플릿은 사용자에게 보여지는 UI부분을, 뷰는 실질적으로 프로그램 로직이 동작하여 데이터를 가져오고 적절하게 처리한 결과를 템플릿에 전달하는 역할을 수행한다.
웹 클라이언트의 요청을 받고, 장고에서 MVT 패턴에 따라 처리하는 과정을 요약하면 다음과 같다.
- 클라이언트로부터 요청을 받으면 URLconf를 이용하여 URL을 분석한다.
- URL 분석 결과를 통해 해당 URL에 대한 처리를 담당할 뷰를 결정한다.
- 뷰는 자신의 로직을 실행하면서 만일 데이터 베이스 처리가 필요하면 모델을 통해 처리하고 그 결과를 반환받는다.
- 뷰는 자신의 로직 처리가 끝나면 템플릿을 사용하여 클라이언트에 전송할 HTML 파일을 생성한다.
- 뷰는 최종 결과로 HTML 파일을 클라이언트에게 보내 응답한다.
Model - 데이터베이스 정의
모델은 사용할 데이터에 대한 정의를 담고있는 클래스다.
~~ 내용
URLconf - URL 정의
클라이언트로부터 받은 요청에 들어있는 URL이 urls.py 파일에 정의된 URL 패턴과 매칭되는지를 분석한다.
파이썬의 URL 정의 방식은 전통적인 자바나 PHP 계열의 URL보다 직관적이고 이해하기가 쉽다. 그래서 이러한 방식을 Elegent URL (우아한?! URL)이라고 부른다. URL을 정의하기 위해서는 아래 예제처럼 urls.py 파일에 URL과 처리함수 (뷰)르 매핑하는 파이썬 코드를 작성하면 된다. 이러한 URL/뷰 매핑을 URLconf라고 한다.
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>', views.article_detail),
]
위의 예시에서 article/2003 부분이 URL이고 views.special_case_2003 부분이 처리함수(뷰)이다.
장고에서 URL을 분석하는 순서
웹 클라이언트가 웹 서버에 페이지 요청시, 장고에서 URL을 분석하는 순서를 간단히 요약하면 아래와 같다.
- setting.py 파일의 ROOT_URLCONF 항목을 읽어 최상위 URLconf (urls.py)의 위치를 알아낸다.
- URLconf를 로딩하여 urlpatterns 변수에 지정되어있는 URL 리스트를 검사한다.
- 위에서부터 순서대로 URL 리스트의 내용을 검사하면서 URL 패턴이 매치되면 검사를 종료한다.
- 매치된 URL의 뷰를 호출한다. 여기서 뷰는 함수 또는 클래스의 메소드다. 호출시 HttpRequest 객체와 매칭할 때 추출된 단어들을 뷰에 인자로 넘겨준다.
- URL 리스트 끝까지 검사했는데도 매칭에 실패하면 에러를 처리하는 뷰를 호출한다.
Path Converter
위의 코드 예제를 보면 URL 패턴을 정의할 때 int:year 처럼 꺾쇠를 사용하는 부분이 있다. 이 꺾쇠 부분을 장고에서는 Path converter라고 부르는데, 이는 URL 패턴의 일부 문자열을 추출하기 위한 것이며, type:name 형식으로 사용한다.
str | /(슬래시) 를 제외한 모든 문자열과 매치된다. 타입이 지정되지 않았다면 디폴트로 str 타입을 사용한다. |
int | 0 또는 양의 정수와 매치된다. 매치된 정수는 파이썬의 int 타입으로 변환된다. |
slug | slug 형식의 문자열 (ASCII, 숫자, 하이픈, 밑줄로만 구성됨)과 매치된다. |
uuid | UUID 형식의 문자열과 매치된다. 매치된 문자열은 파이썬의 uuid 타입으로 변환된다. |
path | /(슬래시)를 포함한 모든 문자열과 매치된다. 이는 URL 패턴의 일부가 아니라 전체를 추출하고자 할 때 많이 사용한다. |
URL 패턴에서의 정규표현식 (regular expression)
URL 패턴에 정규표현식을 사용하면 URL을 좀 더 세밀하게 다룰 수 있다. 예를 들자면 아래와 같다.
from django.urls import path, re_path
from . import views
urlpatterns = [
path('article/2003/', views.special_case_2003),
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[₩w-]+/$', views.article_detail)
]
path() 함수에서의 int:year 부분이 re_path() 함수에서는 (?P[0-9]{4}) 처럼 정규표현식으로 사용하면서, 모든 정수가 아니라 0-9로 이뤄진 4자리 숫자만 매치되도록 한정하고 있다.
보통은 path() 함수를 많이 사용하고, URL을 통해 좀 더 정교하게 정의하고자 할때는 re_path() 함수와 정규표현식을 사용한다. 정규표현식에 사용되는 문자의 의미는 아래와 같다.
표현 | 정의 |
. (dot) | 모든 문자 하나 (any single character) |
^ | 문자열의 시작 |
$ | 문자열의 끝 |
[ ] | [ ] 괄호에 있는 문자 하나, 예를들어 [akz]라면 a 또는 k 또는 z |
[^ ] | [ ] 괄호에 있는 문자 이외의 문자 하나. 만일 [^ab]면 a와 b를 제외한 문자 하나 |
* | 0번 이상의 반복. {0,}와 동일 |
+ | 1번 이상의 반복. {1,} 와 동일 |
? | 0번 또는 1번 반복. {0, 1}와 동일 |
{n} | n번 반복 |
{m, n} | 최소 m 번에서 최대 n번까지 반복 |
| | 예를들어 A|B라면 A 또는 B |
[a-z] | a에서 z 까지 임의의 문자. 즉 영문 소문자 한개 |
₩w | 영문, 숫자 또는 밑줄(_) 한개. [0-9a-zA-Z]와 동일 |
₩d | 숫자 한개. [0-9]와 동일 |
View - 로직 정의
일반적으로 뷰는 웹 요청을 받아서 데이터 베이스 접속 등 해당 어플리케이션의 로직에 맞는 처리를 하고, 그 결과 데이터를 HTML로 변환하기 위하여 템플릿 처리를 한 후에 최종 HTML로 된 응답 데이터를 웹 클라이언트로 반환하는 역할을 한다.
장고에서 뷰는 함수 또는 클래스의 메소드로 작성되며, 웹 요청을 받고 응답을 반환해준다. 다양한 형태의 응답 데이터를 만들어 내기 위한 로직을 뷰에 작성하는 것인데, 이러한 뷰는 보통 views.py 파일에 작성하지만 원한다면 다른 파일에 작성해도 무방하다. 다만 파이썬 경로에 있는 파일이어야 장고가 찾을 수 있다.
간단한 예시로, 현재 날짜와 시간을 HTML로 반환해주는 뷰를 작성해보자.
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now();
html = "<html><body>It is now %s</body></html>" % now
return HttpResponse(html)
이 경우 클래스가 아니라 함수로 뷰를 작성한 예시이다. 뷰 함수는 첫번째 인자로 HttpRequest 객체를 받는다. 그리고 필요한 처리를 한 후에 최종적으로 HttpResponse 객체를 반환해준다.
위의 예시에서는 HTML코드를 뷰 함수 내에 직접 사용했지만, 보통은 별도의 탬플릿 파일에 HTML 코드를 작성한다. 즉, 뷰는 별도로 작성된 템플릿 파일을 해석해서 HTML 코드를 생성하고 이를 HttpResponse 객체에 담아서 클라이언트에게 응답한다.
Template - 화면 UI 정의
장고가 클라이언트에 반환하는 최종 응답은 HTML 텍스트다. 개발자가 응답에 사용할 *.html 파일을 작성하면, 장고는 이를 해석해서 최종 HTML 텍스트 응답을 생성하고, 이를 클라이언트에게 보내준다.
템플릿 파일은 *.html 확장자를 가지며, 장고의 템플릿 시스템 문법에 맞게 작성한다. 유의할 점은 템플릿 파일을 적절한 디렉토리에 위치시켜야 한다는 점이다. 즉, 장고에서 템플릿 파일을 찾는 방식을 이해하고 있어야하며, 장고는 그에 맞는 위치에 템플릿 파일이 위치해야 템플릿 파일을 찾을 수 있다.
장고에서 템플릿 파일을 찾을 때는 TEMPLATE_DIRS 및 INSTALLED_APPS에서 지정된 앱의 디렉토리를 검색한다. 이 항목들은 프로젝트 설정 파일인 settings.py에 정의되어 있다. 여러개의 디렉토리를 지정할 수 있는데, 지정된 순서대로 디렉토리를 검색하여 템플릿 파일을 찾는다.
MVT 코딩 순서
무엇을 먼저 코딩해야하는지는 정해진 것이 없다. UI 화면을 생각하면서 로직을 풀어나가는 것이 쉬울 때에는 보통 템플릿을 먼저 코딩한다.
내가 본 책에서는.. 아래 순서와 같이 코딩을 한다고 했다.
- 프로젝트 뼈대 만들기 : 프로젝트 및 앱 개발에 필요한 디렉토리와 파일 생성
- 모델 코딩하기 : 테이블 관련 사항을 개발(models.py, admin.py 파일)
- URLconf 코딩하기 : URL 및 뷰 매핑 관계를 정의 (urls.py 파일)
- 템플릿 코딩하기 : 화면 UI 개발 (templates/디렉토리 하위의 *.html 파일들)
- 뷰 코딩하기 : 어플리케이션 로직 개발 (views.py 파일)
'Computer Engineering > Django 장고' 카테고리의 다른 글
[Django/장고] 모바일 앱을 위한 장고 (0) | 2019.07.03 |
---|---|
[Django/장고] Django REST Framework 튜토리얼 (0) | 2019.06.28 |
[Django/장고] DRF(Django Rest Framework)란 (0) | 2019.06.28 |
댓글
이 글 공유하기
다른 글
-
[Django/장고] 모바일 앱을 위한 장고
[Django/장고] 모바일 앱을 위한 장고
2019.07.03 -
[Django/장고] Django REST Framework 튜토리얼
[Django/장고] Django REST Framework 튜토리얼
2019.06.28 -
[Django/장고] DRF(Django Rest Framework)란
[Django/장고] DRF(Django Rest Framework)란
2019.06.28