/ PYTHON

Python Django 웹 프레임워크(7) - Django의 개발방식

Python 기초강의는 여러 절로 구성되어 있습니다.


Django의 개발방식

간단한 웹 프로그램을 작성해봤으니 이제 우리가 작업한 내용을 간단하게 정리해 보도록 하겠습니다.

한가지 기억해야 할 점은 다른 언어(예를 들면 Java Servlet)에서는 전체 프로그램을 Web Application이라고 부릅니다. 우리가 작업한 Poll Project를 Web Application이라고 한다는 것이죠.

하지만 Django에서는 약간 다르게 표현합니다. Django에서는 전체 프로그램을 Project라고 표현합니다. 그리고 모듈화된 단위 프로그램들을 application 이라고 표현합니다. 즉, application의 집합이 project가 되는 개념입니다.

Django는 이런 application을 개발할 때 기본적으로 MVT pattern에 따라서 개발합니다.

MVT Pattern

일반적으로 application을 개발할 때 흔히 사용하는 구조는 MVC pattern입니다. MVC pattern은 프로그램의 구성 요소를 Model-View-Controller로 구분해 한 요소가 다른 요소에 미치는 영향을 최소화 하도록 설계하는 방식을 의미합니다.

Django도 이런 MVC pattern 개념을 그대로 받아들여서 사용합니다. 단, MVC pattern에서의 View를 Template으로 Controller를 View라고 표현하며 이를 MVT pattern이라고 합니다.

장고의 MVT pattern을 그림을 묘사하면 아래와 같습니다.

python django MVT

웹 클라이언트로부터 요청을 받고, Django에서 MVT pattern에 따라서 처리하는 과정을 살펴보면 다음과 같습니다.

  • 클라이언트로부터 요청을 받으면 URLConf를 이용하여 URL을 분석합니다.
  • URL 분석 결과를 통해 해당 URL에 대한 처리를 담당한 View를 결정합니다.
  • View는 자신의 로직을 실행하면서 데이터베이스 처리가 필요하면 Model을 통해 처리합니다.
  • View는 로직처리가 끝나면 Template을 사용하여 클라이언트에게 전송할 HTML 파일을 생성합니다.
  • View는 최종결과로 HTML 파일을 클라이언트에게 전송합니다.

Model

Model은 사용될 데이터에 대한 정의를 담고 있는 Django의 class입니다. Django는 ORM 기법을 사용하여 데이터베이스를 class로 mapping해서 사용할 수 있습니다. 쉽게 말하면 하나의 Model class는 하나의 Table에 mapping되고 Model class의 속성은 Table의 column에 mapping됩니다.

장점은 무엇일까요?

ORM을 이용하면 Database에 대한 처리를 SQL없이 class를 다루는 것처럼 할 수 있어서 편리합니다. 또한 Database Engine을 바꾸어도 ORM을 통한 API는 변경할 필요가 없습니다.

간단한 예로 아래의 Model class를 예로 들어보죠


from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

위의 Model class의 정의는 내부적으로 다음의 SQL 명령을 사용하여 Database Table을 생성하게 됩니다.


CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

  • 위에서 보듯이 Table명은 application명과 Model class명을 _ 로 연결하고 모두 소문자로 표현합니다. 다른 이름으로 직접 지정할 수 도 있습니다.

  • PRIMARY KEY는 Person class에서 지정하지 않아도 Django에서 자동으로 부여합니다. 이 부분 역시 직접 지정할 수 도 있습니다.

URLConf

클라이언트로부터 요청을 받으면 Django는 가장 먼저 요청에 들어 있는 URL을 분석합니다. 즉, URL이 urls.py 파일에 정의된 URL pattern과 매칭되는지를 분석한다는 거죠.

Python의 URL 정의 방식을 Elegant URL이라고 부릅니다. 기존 다른 언어의 URL 정의방식보다 쉽고 직관적이기 때문입니다.

URL을 정의하기 위해서는 urls.py 파일에 URL과 View 함수를 매핑하는 코드를 작성해야 합니다. 이를 URLConf 라고 합니다. 아래는 예제로 작성된 urls.py입니다.


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),
]

웹 클라이언트가 웹 서버에 Request를 보낼 때, Django에서 URL을 분석하는 순서를 보면 다음과 같습니다.

  • settings.py 파일의 ROOT_URLCONF 항목을 읽어서 최상위 URLConf 파일의 위치를 알아냅니다.
  • URLConf를 로딩하여 URL list를 검사합니다.
  • 검사 순서는 위에서부터 순서대로 URL list를 검사하며 URL pattern이 매치되면 검사를 종료합니다.
  • 매치된 View 함수를 호출합니다. 호출 시 HttpRequest객체와 URL에서 추출된 데이터를 View 함수에 인자로 넘겨줍니다.
  • URL list 끝가지 검사했는데도 매칭에 실패하면 에러를 처리하는 View 함수를 호출합니다.

여기서 주의해야 할 부분은 <int:month> 처럼 꺽쇠를 사용하는 부분입니다. 이는 URL 에서 일부 데이터를 추출하기 위한 것으로 <type:name> 형태로 사용합니다. 만약 요청 URL이 /articles/2020/이라면 호출되는 View 함수는 view.year_archive(request,year=2020) 처럼 호출합니다.

이런 꺽쇠 부분을 Django에서는 Path Converter라고 부릅니다. 여기에서 사용되는 타입은 str, int, slug, path 등이 있습니다.

  • str : /를 제외한 모든 문자열과 매치됩니다. 타입이 지정되지 않으면 default로 str입니다.
  • int : 0 또는 양의 정수와 매치됩니다.
  • slug : slug형식의 문자열과 매치됩니다. (ASCII, 숫자, 하이픈, 밑줄)
  • path : /를 포함한 모든 문자열과 매치됩니다. 이는 URL의 일부가 아니라 전체를 추출하고자 할때 사용됩니다.

또한 Regular Expression(정규 표현식)을 사용해서 URL을 좀 더 세밀하게 표현 할 수 도 있습니다. 이 부분은 책이나 다른 문서를 참조하세요~

View

View는 일반적으로 Request를 받아서 Database 처리 등 로직에 맞는 처리를 하고, 그 결과 데이터를 HTML로 변환하기 위해서 Template 처리를 한 후 최종 HTML로 된 응답 데이터를 웹 클라이언트에게 반환하는 역할을 수행합니다.

일반적으로 views.py 파일에 작성되며 다른 파일에 작성해도 상관은 없습니다.

간단한 예로 현재의 날짜와 시간을 HTML로 반환해주는 View 함수는 다음과 같습니다.


from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datatime.datetime.now()
    html = "<html><body>현재 시각은 : %s</body></html>" % now
    return httpResponse(html)

만약 Error를 반환하고 싶다면 아래처럼 HttpResponseNotFound와 같은 에러 응답 객체를 반환하면 됩니다.


return HttpResponseNotFound("<h1>페이지를 찾을 수 없습니다.</h1>")

Template

Django가 클라이언트에게 반환하는 최종 응답은 HTML text입니다. 개발자가 응답에 사용할 html 파일을 작성하면, 장고는 이를 해석해서 데이터를 적용해 최종 HTML text를 생성하고 이를 클라이언트에게 보내주게 됩니다.

이런 과정에서 개발자가 작성하는 html 파일을 Template 파일이라고 부릅니다.

Template file은 .html 확장자를 가지며 Django의 Template 시스템 문법에 맞게 작성합니다. 조심해야 할 사항은 이 Template 파일을 적절한 디렉토리에 위치시켜야 한다는 점 입니다.

Django에서 Template 파일을 찾을 때 TEMPLATE_DIRSINSTALLED_APPS에서 지정된 application의 디렉토리를 검색합니다. 이 항목들은 settings.py에 지정되어 있습니다.

End.


Python 강좌는 아래의 책과 사이트를 참조했습니다. 조금 더 자세한 사항을 알고 싶으시면 해당 사이트를 방문하세요!!