-
Django - 01 애플리케이션 개발 방식Django 2021. 3. 29. 20:15
웹 사이트를 설계할 때 가장 먼저 해야 할 일은 프로그램이 해야 할 일을 나누어서 모듈화 하는 것이다. 웹 사이트의 전체 프로그램 또는 모듈화된 단위 프로그램을 애플리케이션이라고 한다. 즉, 코딩할 대상을 애플리케이션이라고 부른다.
장고에서는 애플리케이션의 개념을 웹 서버 개발 측면에서 좀 더 구체화 한다. 웹 사이트에 대한 전체 프로그램을 프로젝트라 하고, 모듈화된 단위 프로그램을 애플리케이션이라 부른다. 즉, 애플리케이션 프로그램들이 모여서 프로젝트를 개발하는 개념이다.
MVT 패턴
MVC(Model-View-Controller)패턴은 데이터, 사용자 인터페이스, 데이터를 처리하는 로직을 구분해서 한 요소가 다른 요소들에 영향을 주지 않도록 설계하는 방식이다. 이런 방식으로 개발하면 디자이너는 데이터나 로직에 신경 쓰지 않고 화면 UI를 설계할 수 있다.
장고 프레임워크에서는 View를 Template, Controller는 View라고 표현하며, MVC를 MVT 패턴이라고 한다.
Model은 데이터베이스에 저장되는 데이터를 의미하고, Template은 사용자에게 보이는 UI, View는 프로그램 로직이 동작하여 데이터를 가져오고 결과를 템플릿에 전달하는 역할을 수행한다.
장고에서 웹 클라이언트의 요청을 받고 MVT 패턴에 따라 처리하는 과정을 요약하면 다음과 같다.
- 클라이언트로부터 요청을 받으면 URLconf를 이용하여 URL을 분석한다.
- URL 분석 결과를 통해 해당 URL에 대한 처리를 담당할 View를 결정한다.
- View는 로직을 실행하면서, 만일 데이터베이스 처리가 필요하면 Model을 통해 처리하고 결과를 반환받는다.
- View는 자신의 로직 처리가 끝나면 Template을 사용하여 클라이언트에 전송할 HTML 파일을 생성한다.
- View는 최종 결과로 HTML 파일을 클라이언트에게 보내 응답한다.
Model - 데이터베이스 정의
모델은 사용될 데이터에 대한 정의를 담고 있는 클래스다. ORM 기법을 사용하여 애플리케이션에서 사용할 데이터베이스를 클래스로 매핑해서 코딩할 수 있다. 즉, 하나의 모델 클래스는 하나의 테이블에 매핑되고, 모델 클래스의 속성은 테이블의 컬럼에 매핑된다.
ORM 기법을 사용하여 테이블을 클래스로 매핑하면, 데이터베이스에 대한 액세스를 SQL 없이도 클래스를 다룰 수 있어서 편리하다. 또한 SQLite3, MySQL, PostgreSQL 등 데이터베이스 엔진을 변경하더라도 ORM을 통한 API는 변경할 필요가 없기 때문에, 필요에 따라 데이터베이스 엔진을 쉽게 변경할 수 있다.
ORM이란?
: Object-Relational-Mapping은 객체와 관계형 데이터베이스를 연결해주는 역할을 한다. 기존의 웹 프로그래밍에서 데이터베이스에 접근하려면 SQL 및 데이터베이스에 접근하기 위한 드라이버 API 등에 대해 알아야 했다. 하지만 ORM에서는 데이터베이스 대신에 객체(클래스)를 사용해 데이터를 처리할 수 있다. ORM이 자동으로 적절한 SQL 구문이나 데이터베이스 API를 호출해서 처리해주기 때문이다.CREATE TABLE myapp_person ( "id" serial NOT NULL PRIMARY KEY, "first_name" varchar(30) NOT NULL, "last_name" varchar(30) NOT NULL );
위의 코드는 SQL 명령을 사용하여 만든 Person 테이블 클래스다.
from django.db import models class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
위의 코드는 Person 테이블을 장고의 Person 모델 클래스로 정의한 것이다.
장고는 테이블 및 컬럼을 생성하기 위한 규칙들이 있다.
- 테이블명은 애플리케이션명과 모델 클래스명을 밑줄(_)로 연결하고, 모두 소문자로 표시한다.
- Primary Key는 Person 클래스에서 정의하지 않아도 장고에서 자동으로 부여한다. 개발자가 직접 지정할 수도 있다.
URLconf - URL 정의
클라이언트로부터 요청을 받으면 장고는 요청에 들어있는 URL을 분석한다. 요청에 들어있는 URL이 urls.py 파일에 정의된 URL 패턴과 매칭 되는지 분석한다.
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), ]
위의 예제처럼 URL과 처리 함수를 매핑하는 파이썬 코드를 작성하면 된다. 이러한 URL/View 매핑을 URLconf라고 한다.
위 예시에서 articles/2003/ 부분이 URL이고 views.special_case_2003 부분이 처리함수(뷰)다.
위와 같이 URL과 처리 함수를 별도로 정의하고, 이 둘을 매핑하는 방법은 많은 유연성을 제공한다.
웹 클라이언트가 웹 서버에 페이지 요청 시, 장고에서 URL을 분석하는 순서는 다음과 같다.
- setting.py 파일의 ROOT_URLCONF 항목을 읽어 최상의 URLconf(urls.py)의 위치를 알아낸다.
- URLconf를 로딩하여 urlpatterns 변수에 지정되어 있는 URL 리스트를 검사한다.
- 위에서부터 순서대로 URL 리스트의 내용을 검사하면서 URL 패턴이 매치되면 검사를 종료한다.
- 매치된 URL의 뷰를 호출한다(뷰는 함수 또는 클래스의 메소드다). 호출 시 HttpRequest 객체와 매칭 할 때 추출된 단어들을 뷰에 인자로 넘겨준다.
- URL 리스트 끝까지 검사했는데도 매칭에 실패하면 에러를 처리하는 뷰를 호출한다.
URL 패턴의 일부 문자열을 추출하기 위해서는 <type:name> 형식을 사용한다. 위의 예제를 보면 URL 패턴을 정의할 때 <int:year>처럼 꺾쇠를 사용하는 부분이 있다. 꺾쇠 부분을 장고에서는 Path Converter라고 부르는데, 사용되는 타입은 다음과 같다. (개발자가 추가로 타입을 등록할 수 있다.)
- str : /(슬래시)를 제외한 모든 문자열과 매치된다. 타입이 지정되지 않았다면 디폴트로 str 타입을 사용한다.
- int : 0 또는 양의 정수와 매치된다. 매치된 정수는 int 타입으로 변환된다.
- slug : slug 형식의 문장열(ASCII, 숫자, 하이픈)과 매치된다.
- uuid : UUID 형식의 문자열과 매치된다. 매치된 문자열은 파이썬의 UUID 타임으로 변환된다.
- path : 모든 문자열과 매치된다. URL 패턴의 일부가 아니라 전체를 추출하고자 할 때 많이 사용된다.
View - 로직 정의
장고는 웹 요청에 있는 URL을 분석하고, 그 결과로 해당 URL에 매핑된 뷰를 호출한다.
뷰는 웹 요청을 받아서 데이터베이스 접속 등 해당 애플리케이션의 로직에 맞는 처리를 하고, 그 결과 데이터를 HTML로 변환하기 위하여 템플릿 처리를 한 후에, 최종 HTML로 된 응답 데이터를 웹 클라이언트로 반환하는 역할을 한다.
장고에서의 뷰는 함수 또는 클래스의 메서드로 작성되며, 웹 요청을 받고 응답을 반환해준다. 다양한 형태의 응답 데이터를 만들어내기 위한 로직을 뷰에 작성한다. 뷰는 보통 views.py 파일에 작성하지만, 다른 파일에 작성해도 무방하다.
예로 현재의 날짜와 시간을 HTML로 반환해주는 뷰를 작성해봤다.
from django.http import HttpResponse import datetime def current_data(request): now = datetime.datetime.now() html = "<html><body>It is now {}.</body></html>".format(now) return HttpResponse(html)
이 경우는 클래스가 아니라 함수로 뷰를 작성한 예시이다. 뷰 함수는 첫 번째 인자로 HttpRequest 객체를 받는다. 그리고 필요한 처리를 한 후에 최종적으로 HttpResponse 객체를 반환한다. 만일 에러를 반환하고 싶다면 HttpResponseNotFound 에러 응답 객체를 반환하면 된다.
앞의 예시에서는 뷰 함수 내에 직접 사용했지만, 보통은 별도의 템플릿 파일에 HTML 코드를 작성한다. 즉 뷰는 별도의 템플릿 파일을 해석해서 HTML 코드를 생성하고 HttpResponse 객체에 담아서 클라이언트에게 응답한다.
Template - 화면 UI 정의
클라이언트에게 반환하는 최종 응답은 HTML 텍스트다. 응답에 사용할 *.html 파일을 작성하면, 장고는 해석 후 최종 HTML 텍스트 응답을 생성하고, 클라이언트에게 보내준다. 클라이언트(보통 웹 브라우저)는 응답으로 받은 HTML 텍스트를 해석해서 웹 브라우저 화면에 UI 를 보여주는 것이다.
이런 과정에서 개발자가 작성하는 *.html 파일을 템플릿이라 부르며, UI 모습을 템플릿 문법에 맞게 작성한다.
장고는 자체 템플릿 엔진을 갖고 있어서 디자이너도 쉽게 이해할 수 있는 문법을 제공한다.
장고에서 템플릿 파일을 찾을 때는 TEMPLATES 및 INSTALLED_APPS에서 지정된 앱의 디렉터리를 검색한다. 이 항목들은 settings.py 파일에 정의되어 있다. 여러 개의 디렉토리를 지정할 수 있는데, 지정된 순서대로 디렉토리를 검색하여 템플릿 파일을 찾는다.
MVT 코딩 순서
무엇을 먼저 코딩해야 하는지에 대해 정해진 순서는 없다. MVT 방식에 따르면 화면 설계는 뷰와 템플릿 코딩으로 연결되고, 테이블 설계는 모델 코딩에 반영된다. 그렇기 때문에 독립적으로 개발할 수 있는 모델을 먼저 코딩하고, 뷰와 템플릿은 서로 영향을 미치므로 모델 이후에 같이 코딩하는 것이 일반적이다.
뷰와 템플릿의 코딩 순서도 굳이 정할 필요는 없지만, UI 화면을 생각하면서 로직을 풀어나가는 것이 쉽기 때문에 보통은 템플릿을 먼저 코딩한다. 다만 클래스형 뷰처럼 뷰의 코딩이 매우 간단한 경우에는 뷰를 먼저 코딩한다.
'Django' 카테고리의 다른 글
Django - 03 Model 코딩 (0) 2021.03.31 Django - 02 애플리케이션 설계 / 프로젝트 뼈대 만들기 (0) 2021.03.29 Django - 장고의 특징 (0) 2021.03.29 Django - 웹 서버 (0) 2021.03.29