기초부터 첫 앱까지…장고 6.0으로 시작하는 파이썬 웹 개발 가이드
컨텐츠 정보
- 조회 371
본문
장고(Django)는 만능형 파이썬 웹 프레임워크로, 루비 온 레일스(Ruby on Rails)에 착안해 개발됐으며, 더 빠르고 쉬운 웹 개발을 위해 루비 온 레일스의 많은 메타포를 그대로 차용했다. 풍부한 기능과 유연성을 갖춘 장고는 파이썬에서 가장 널리 사용되는 웹 프레임워크 중 하나로 성장했다.
최신 버전인 장고 6.0은 크고 작은 웹 애플리케이션을 구축하는 데 필요한 거의 모든 기능을 제공하며 인기가 높은 만큼 다양한 시나리오에 맞는 예제와 도움말도 쉽게 찾을 수 있다. 또한 장고는 점진적으로 애플리케이션을 발전시키면서 기능을 추가하기 위한 툴, 그리고 데이터 스키마가 있을 경우 이를 마이그레이션하기 위한 툴도 제공한다.
구성요소가 많고 “내부적으로” 상당히 세세한 구성이 필요하다는 점에서 복잡하다는 비판도 있지만 장고를 사용하면 비교적 짧은 시간 안에 간단한 파이썬 애플리케이션을 만들어 실행하고 필요에 따라 기능을 확장할 수 있다.
이 기사에서는 장고 6.0을 사용해 기본적인 애플리케이션을 만드는 과정을 안내하고, 웹 개발자에게 가장 중요한 장고 6 릴리스의 여러 기능에 대해서도 간략히 살펴본다.
들어가기 전 : 필요한 파이썬 버전
장고 6.0을 설치하려면 파이썬 3.12 이상이 필요하다. 최선은 자신이 구상하는 장고 프로젝트에 필요한 모든 기능을 지원하는 최신 파이썬 버전을 사용하는 것이지만 최신 버전으로 업데이트할 수 없어 이전 버전의 파이썬을 사용해야 하는 상황이라면 장고 5를 사용해도 된다. 장고의 파이썬 버전 표에서 사용할 수 있는 버전을 확인할 수 있다.
장고 설치
파이썬 3.12 이상이 설치돼 있다면 장고를 설치하기 위한 첫 단계는 가상 환경을 만드는 것이다. venv에 장고를 설치하면 장고 및 관련 라이브러리가 기본 파이썬 설치와 분리된다는 이점이 있다.
venv에 대한 참고 사항 : 가상 환경을 사용하지 않고도 하나의 장고 인스턴스를 사용해 여러 프로젝트를 만들 수는 있다. 가상 환경이 필요한 유일한 이유는 각각 서로 다른 프로젝트와 연결된 장고 프레임워크의 여러 포인트 리비전을 격리하는 데 있다.
다음 단계로, 선택한 가상 환경에서 파이썬의 pip 유틸리티를 통해 장고를 설치한다.
pip install django이렇게 하면 장고의 핵심 라이브러리와 장고 프로젝트 관리에 사용되는 명령줄 유틸리티 django-admin이 설치된다.
새 장고 프로젝트 만들기
장고 인스턴스는 프로젝트와 앱, 두 개의 계층으로 구성된다.
- 프로젝트는 자체 데이터베이스 구성과 설정, 앱이 있는 장고 인스턴스다. 앞으로 사용할 모든 사이트 수준 구성을 저장하는 장소라고 생각하면 된다.
- 앱은 자체 경로와 렌더링 로직이 있는 프로젝트의 하위 요소다. 하나의 장고 프로젝트 안에 여러 앱이 위치할 수 있다.
새 장고 프로젝트를 만들려면 장고가 설치된 가상 환경을 활성화한 다음 프로젝트를 저장할 디렉터리로 이동해 다음을 입력한다.
django-admin startproject 은 프로젝트 이름인 동시에 프로젝트가 저장될 하위 디렉터리의 이름이기도 하다. myproj와 같이 파이썬이나 장고 내부적으로 사용되는 이름과 충돌하지 않는 이름을 사용해야 한다.
새로 생성된 디렉토리에는 명령줄에서 앱 동작을 제어하는 데 사용되는 manage.py 파일, 그리고 또 다른 하위 디렉토리(마찬가지로 프로젝트 이름이 사용됨)가 있으며, 이 하위 디렉터리 안에는 다음 파일이 포함된다.
__init__.py: 파이썬에서 하위 디렉터리를 코드 모듈로 지정하는 데 사용된다.settings.py: 프로젝트에 사용되는 설정이 포함된다. 가장 일반적인 설정은 이미 입력된 상태로 제공된다.urls.py: 장고 프로젝트에서 사용할 수 있는 경로나 URL, 또는 프로젝트가 응답을 반환할 경로나 URL을 나열한다.wsgi.py: 아파치 HTTP, 엔진엑스(Nginx)와 같은 WSGI 호환 웹 서버에서 프로젝트의 앱을 지원하는 데 사용된다.asgi.py: ASGI 호환 웹 서버에서 프로젝트의 앱을 지원하는 데 사용된다. ASGI는 비동기 서버와 애플리케이션을 위한 비교적 새로운 표준으로, uvicorn 등 이를 지원하는 서버가 필요하다. 장고는 비동기 애플리케이션에 대한 네이티브 지원을 최근에야 추가했다. 참고로 비동기 애플리케이션은 비동기 호환 서버에 호스팅돼야 완전한 효과를 낼 수 있다.
이제 프로젝트를 테스트해서 정상 작동하는지 확인한다. 명령줄에서 프로젝트의 manage.py 파일이 포함된 디렉터리로 이동해 다음을 입력한다.
python manage.py runserver이렇게 하면 개발 웹 서버(http://127.0.0.1:8000/)가 시작된다. 링크를 방문하면 설치가 성공했음을 알려주는 간단한 환영 페이지가 표시될 것이다.
장고 프로젝트를 공개적으로 서비스하는 데 개발 웹 서버를 사용하면 안 된다. 개발 웹 서버는 로컬 테스트 전용으로, 공개 애플리케이션에 맞춰 확장되도록 설계되지 않았기 때문이다.
장고 애플리케이션 만들기
다음으로, 이 프로젝트 내부에 애플리케이션을 만든다. manage.py가 있는 디렉토리로 이동해 다음 명령을 입력한다.
python manage.py startapp myapp애플리케이션을 위한 myapp이라는 하위 디렉토리가 생성된다. 이 디렉토리에는 다음이 포함된다.
- migrations 디렉토리 : 다른 데이터 스키마 버전으로 사이트를 마이그레이션하는 데 사용되는 코드가 포함된 디렉토리다. 장고 프로젝트에는 일반적으로 데이터베이스가 있으므로 데이터베이스를 위한 스키마는 그 스키마의 변경 사항과 함께 프로젝트의 일부로 관리된다.
admin.py: 장고에 내장된 관리 툴에서 사용하는 객체가 포함된다. 앱에 관리자 인터페이스 또는 특권 사용자가 있다면 그와 관련된 객체를 이 파일에서 설정한다.apps.py: 앱에 대한 구성 정보를AppConfig객체를 통해 프로젝트 전체에 제공한다.models.py: 앱에서 데이터베이스와 상호작용하는 데 사용되는 데이터 구조를 정의하는 객체가 포함된다.tests.py: 사이트의 기능과 모듈이 의도한 대로 작동하는지 확인하기 위해 사용자가 만드는 모든 테스트는 이 디렉토리에 저장된다.views.py: 응답을 렌더링하고 반환하는 함수가 포함된다.
애플리케이션 작업을 시작하려면 먼저 프로젝트에 애플리케이션을 등록해야 한다. 다음과 같이 myproj/settings.py를 편집해서 INSTALLED_APPS 목록 맨 위에 한 줄을 추가한다.
INSTALLED_APPS = [ "myapp.apps.MyappConfig", "django.contrib.admin", ...myproj/myapp/apps.py에는 사전에 생성된 MyappConfig라는 객체가 있을 것이다.
장고 애플리케이션에 경로와 뷰 추가하기
장고 애플리케이션은 요청 처리에 다음과 같은 기본적인 패턴을 사용한다.
- 요청이 수신되면 장고는 URL을 파싱해서 적용할 경로를 찾는다.
- 경로는
urls.py에 정의되며, 각 경로는 뷰, 즉 클라이언트로 보낼 데이터를 반환하는 함수에 연결된다. 뷰는 장고 프로젝트 어디에나 위치할 수 있지만 자체 모듈로 구성하는 것이 가장 좋다. - 뷰에는 템플릿의 결과가 포함될 수 있다. 템플릿은 요청된 데이터를 특정 설계에 따라 포맷하는 코드다.
이러한 모든 요소가 어떻게 맞물려 작동하는지 이해하기 위해, 이제부터 샘플 애플리케이션의 기본 경로를 수정해 맞춤형 메시지를 반환하도록 해보자.
경로는 urls.py의 urlpatterns라는 목록에 포함된다. 샘플 urls.py를 열면 미리 정의된 urlpatterns를 볼 수 있다.
urlpatterns = [ path('admin/', admin.site.urls),]path 함수(장고 내장 함수)는 경로와 뷰 함수를 인수로 받아 URL 경로에 대한 참조를 생성한다. 기본적으로 장고는 사이트 관리에 사용되는 admin 경로를 생성하지만 이 경우에는 직접 자체 경로를 만들어야 한다.
다른 항목을 추가해서 전체적으로 다음과 같이 보이도록 한다.
from django.contrib import adminfrom django.urls import include, pathurlpatterns = [ path('admin/', admin.site.urls), path('myapp/', include('myapp.urls'))]include 함수는 장고에 myapp.urls에서 더 많은 경로 패턴 정보를 찾도록 지시한다. 이 파일에서 발견된 모든 경로는 최상위 경로 myapp에 연결된다(예 : http://127.0.0.1:8080/myapp).
다음으로, myapp에 새 urls.py를 생성하고 다음을 추가한다.
from django.urls import pathfrom . import viewsurlpatterns = [ path('', views.index)]장고가 각 URL의 앞에 슬래시를 붙이므로 사이트의 루트(/)를 지정하려면 URL로 빈 문자열을 제공하면 된다.
이제 myapp/views.py 파일을 다음과 같이 편집한다.
from django.http import HttpResponsedef index(request): return HttpResponse("Hello, world!")장고에 기본적으로 포함된 django.http.HttpResponse는 제공된 문자열로부터 HTTP 응답을 생성한다. 수신되는 HTTP 요청 정보가 포함된 요청은 뷰 함수의 첫 번째 매개변수로 전달돼야 한다.
개발 서버를 재시작한 다음 http://127.0.0.1:8000/myapp/으로 이동하면 브라우저에 “Hello, world!”가 표시되는 것을 볼 수 있다.
장고에서 변수가 있는 경로 추가하기
장고는 변수가 포함된 경로를 구문의 일부로 받을 수 있다. 예를 들어 year/ 형식의 URL을 받고 자한다고 생각해 보자. 다음 항목을 urlpatterns에 추가하면 된다.
path(‘year/’, views.year)그러면 뷰 함수 views.year는 year/1996, year/2010과 같은 경로를 통해 호출된다. 이때 변수 year는 views.year에 매개변수로 전달된다.
직접 해보려면 위의 urlpatterns 항목을 myapp/urls.py에 추가한 다음 myapp/views.py에 다음 함수를 추가하면 된다.
def year(request, year): return HttpResponse('Year: {}'.format(year))사이트에서 /myapp/year/2010으로 이동하면 응답으로 Year: 2010이 표시되는 것을 볼 수 있다. 참고로 /myapp/year/rutabaga와 같은 경로에서는 오류가 발생한다. 변수 year에 적용되는 int: 제약에 따라 그 위치에는 정수만 허용되기 때문이다. 이 외에도 경로에 다양한 포맷 옵션을 사용할 수 있다.
이전 장고 경로와의 하위 호환성 : 이전 버전의 장고에서는 경로 구문이 더 복잡해서 파싱하기가 어려웠다. 예전 구문을 사용해 경로를 추가해야 하는 상황이라면(예를 들어 오래된 장고 프로젝트와의 하위호환성을 위해) 정규식을 사용해 경로를 매칭하는 django.urls.re_path 함수를 사용하면 된다.
장고 템플릿과 템플릿 파셜
장고에 내장된 템플릿 언어를 사용해 데이터를 기반으로 웹 페이지를 만들 수 있다.
장고 앱에 사용되는 템플릿은 프로젝트의 중심 디렉토리인 /templates//에 저장된다. myapp 프로젝트의 경우 myapp/templates/myapp/ 디렉토리다. 디렉토리 구조가 이상해 보일 수 있지만 이 구조 덕분에 장고는 여러 위치에서 템플릿을 찾고 여러 앱에 걸쳐 같은 이름의 템플릿이 충돌하는 상황을 피할 수 있다.
myapp/templates/myapp/ 디렉토리에서 year.html이라는 파일을 생성해 다음 내용으로 채운다.
Year: {{year}}템플릿에서 이중 중괄호 안의 모든 값은 변수로 취급되고 그 외의 요소는 문자 그대로 처리된다.
myapp/views.py를 다음과 같이 수정한다.
from django.shortcuts import renderfrom django.http import HttpResponsedef index(request): return HttpResponse("Hello, world!")def year(request, year): data = {'year':year} return render(request, 'myapp/year.html', data)render 함수는 장고의 “바로가기”, 즉 여러 내장 기능을 편의를 위해 결합한 것으로, 기존 요청 객체를 받아서 사용 가능한 템플릿 위치 목록에서 myapp/year.html을 찾고 딕셔너리 데이터를 템플릿의 컨텍스트로 전달한다. 템플릿은 이 딕셔너리를 템플릿에 사용되는 변수의 네임스페이스로 사용한다. 여기서 템플릿의 {{year}} 변수는 딕셔너리 데이터의 year 키 값, 즉 data["year"]로 대체된다.
장고 템플릿 내에서 데이터를 대상으로 할 수 있는 처리 작업은 의도적으로 제한돼 있다. 장고의 원칙은 가능한 모든 경우 표현과 비즈니스 로직을 분리하는 것이다. 따라서 반복 가능한 객체를 루프로 순환하고 if/then/else 테스트를 수행할 수 있지만, 템플릿 내에서 데이터를 수정하는 것은 바람직하지 않다.
예를 들어 간단한 “if” 테스트는 다음과 같이 작성할 수 있다.
{% if year > 2000 %}21st century year: {{year}}{% else %}Pre-21st century year: {{year}}{% endif %}{% 와 %} 마커는 장고 템플릿 언어로 실행 가능한 코드 블록을 구분한다.
더 정교한 템플릿 처리 언어를 사용하고 싶다면 진자2(Jinja2) 또는 마코(Mako)와 같은 언어를 사용할 수 있다. 장고에는 진자2 백엔드 통합이 포함돼 있지만, 예를 들어 이 기사에서 다루는 “Hello, world!” 경로처럼 HttpResponse 객체에 그 문자열을 반환하는 방식으로 문자열을 반환하는 템플릿 언어라면 그 외에도 무엇이든 사용할 수 있다.
장고 버전 6 이상은 템플릿의 일부를 한 번 정의한 다음 템플릿 전체에서 재사용할 수 있는 방법인 템플릿 파셜을 지원한다. 이를 통해 특정 값을 템플릿 전체에 걸쳐 한 번만 계산해 두면 매번 다시 계산하지 않고 재사용해서 표시할 수 있다.
그 외에 장고로 할 수 있는 일
지금까지 살펴본 내용은 장고 애플리케이션의 가장 기본적인 요소일 뿐이다. 장고에는 그 외에도 웹 프로젝트에서 사용할 수 있는 많은 구성요소가 포함돼 있다. 간단히 살펴보면 다음과 같다.
- 데이터베이스와 데이터 모델 : 장고의 내장 ORM은 데이터 구조와 각 구조 간의 관계, 그리고 이러한 구조의 버전 간 마이그레이션 경로를 정의할 수 있게 해준다.
- 양식 : 뷰는 장고에서 제공하는 일관적인 방법을 통해 사용자에게 입력 양식을 제공하고 데이터를 가져오고 결과를 정규화하고 일관된 오류 보고를 제공할 수 있다. 장고 6에는 제출된 양식이 콘텐츠 주입이나 크로스 사이트 스크립팅(XSS) 공격에 취약하지 않도록 하는 콘텐츠 보안 정책(Content Security Policy)에 대한 지원이 추가됐다.
- 보안과 유틸리티 : 장고에는 캐싱, 로깅, 세션 처리, 정적 파일 처리, URL 정규화를 위한 많은 내장 함수가 포함돼 있다. 또한 암호화 인증서 사용이나 크로스 사이트 위조 방지, 클릭재킹 방지와 같은 일반적인 보안 요구사항에 대응하는 툴도 함께 제공된다.
- 작업(task) : 장고 6에는 사용자에 대한 응답을 지연시키지 않으면서 장시간 실행되는 백그라운드 작업을 생성하고 관리하기 위한 네이티브 메커니즘이 추가됐다. 단, 장고는 작업을 설정하고 추적하는 방법만 제공할 뿐 실제 실행 메커니즘은 제공하지 않는다. 작업용으로 포함된 유일한 백엔드는 테스트를 위한 것이므로 필요하다면 서드파티 솔루션을 추가하거나 장고의 백엔드 작업 코드를 기반으로 직접 제작해야 한다.
dl-itworldkorea@foundryco.com
관련자료
-
링크
-
이전
-
다음






