목표는 "API Server <==> Redis <==> Celery" 구조까지 이해하고, 설계하며 기본적으로 Django를 배포하고 관리하는 것 까지 알아갈 것 이다. 기본적인 웹지식은 가지고 있어야 (적어도 다른 언어 또는 프레임워크로 배포는 해보고 만들어갈 수 있어야) 깊은 이해가 가능하다.
훌륭한 개발자에 의해 만들어진 이 프레임워크는, 웹 개발을 하는데 많은 도움을 주기 때문에 새롭게 웹 개발을 시작할 필요없이 그저 프레임워크를 활용하여 앱 개발에만 집중할 수 있게된다. 무료 오픈소스인데다가, 활발한 커뮤니티들이 있고, 좋은 참고자료와 무료 및 유료 지원을 하는 옵션들이 제공되는 점이 러닝커브 관점과 에러헨들링에 큰 도움이 된다.
아래는 영문의 번역본과 개인 견해야게 덧 붙여진, Django에 대한 글이다.
Django는 "Batteries included" 의 철학을 기반으로 개발자들이 개발하고 싶은 거의 모든것을 개발하는데 도움을 준다. 개발자들이 원하는 것은 모두 하나의 "결과물"의 일부일 것이기 때문에 도달하고자 하는 목표지점은 같으며 이 덕분에 일관된 디자인 룰을 적용하여 광범위한 최신 문서를 제공한다.
'웹 서비스' 라는 같은 결과물을 향해 달리기 위해, '서비스 로직' 과 '기능적인 부분' 에만 철저하게 집중할 수 있도록, 그 외의 것들은 프레임워크가 알아서 해 줄 수 있게 설계된 것이라고 와닿는다.
예를 들면, 장고는 유저의 계정과 비밀번호를 관리하는 안전한 방법을 제공한다. 개발자들의 실수로 세션의 정보를 보안에 취약한 위치에 있는 쿠키(해결책은 쿠키는 그저 key값을 가지도록 하는 반면 실제 데이터는 데이터 베이스에 저장하도록 하는 것입니다)에 넣는 실수를 하는 것이다. 또 달리 쉽게할 수 있는 실수는 비밀번호를 hash를 통하지 않고 그대로 변형없이 저장하는 것이 있다.
비밀번호에 사용되는 hash 는 cryptographic hash function에 의해 생성된 고정된 길이의 값을 가진다. Django는 이렇게 변형되어 입력된 비밀번호가 유효한지 hash 함수를 통해 확인할 수 있다. 하지만 "단방향" 적인 함수의 특성상, 저장된 hash 값을 웹을 공격하는 사람들이 알아낸다고 하더라도 원본 비밀번호는 알아낼 수 없다.
Django 는 SQL 인젝션, 크로스사이트 스크립팅, 크로스사이트 요청 위조 그리고 클릭 하이젝킹 (이러한 공격 방법에 대한 상세 정보는 Website security에서 볼 수 있습니다)과 같은 보안 취약점을 보완할 방법 기본적으로 제공한다.
URLs
: 단일 함수를 통해 모든 URL 요청을 처리하는 것이 가능하지만, 분리된 뷰 함수를 작성하는 것이 각각의 리소스를 유지보수하기 훨씬 쉽다. URL mapper는 요청 URL을 기준으로 HTTP 요청을 적절한 뷰(view)로 보내주기 위해 사용된다. 또한 URL mapper는 URL에 나타나는 특정한 문자열이나 숫자의 패턴을 일치시켜 데이터로서 뷰 함수에 전달할 수 있다.
View
: 뷰는 HTTP 요청을 수신하고 HTTP 응답을 반환하는 요청 처리 함수다. 뷰는 Model을 통해 요청을 충족시키는데 필요한 데이터에 접근한다. 그리고 탬플릿에게 응답의 서식 설정을 맡긴다.
Models
: 모델은 응용프로그램의 데이터 구조를 정의하고 데이터베이스의 기록을 관리(추가, 수정, 삭제)하고 쿼리하는 방법을 제공하는 파이썬 객체(instance)다.
Templates
: 탬플릿은 파일의 구조나 레이아웃을 정의하고(예: HTML 페이지), 실제 내용을 보여주는 데 사용되는 "플레이스홀더"를 가진 텍스트 파일이다. 뷰는 HTML 탬플릿을 이용하여 동적으로 HTML 페이지를 만들고 모델에서 가져온 데이터로 채운다. 탬플릿으로 모든 파일의 구조를 정의할 수 있다. 탬플릿이 꼭 HTML 타입일 필요는 없다. (node에서 pug, ejs 등 / java에서 jpa 등)
spring(MVC)에 비해서 정말 직관적이다. build되고 was에 배포되는 .war가 가지는 장점과 java의 강력한 장점이 있음에도 django가 가지는 설계적 단순함과 빠르게 개발 가능이라는 부분은 정말 앞으로 선택할 가치가 큰 것 같다.
위 사진은 django appplication이 client의 http request를 어떤 흐름으로 처리하는지 러프하게 flow를 나타낸다. (mermaid로 그렸다 ㅎ)
세부 사항은 앞으로 시리즈를 진행하면서 하나 하나 톺하보자.
python -m venv .venv # venv 가상환경 구성
source .venv/bin/activate # 가상환경 실행
which python # 가상환경에 지금 어떤 인터프리터가 사용되는지 -> venv 디렉터리 안에 있는 bin/python이 운영체제에 기본 설치된 파이썬 대신에 사용됨
# ps) 가상환경 나올땐 deactivate
python -m pip install Django # pip을 통해 django 설치
설치잘 되었는지 테스트
또는 python -m django --version
을 통해 확인가능
장고 offical DOCs에서 제공해주는 튜토리얼을 따라가보자. Polls Application 만들자!
django-admin startproject mysite
를 통해 project 생성
mysite 라는 디렉토리(프로젝트)가 생성된다. 기본적인 디렉토리 생성 구조는 아래와 같다.
manage.py: Django 프로젝트와 다양한 방법으로 상호작용 하는 커맨드라인의 유틸리티 입니다. manage.py 에 대한 자세한 정보는 django-admin and manage.py 에서 확인할 수 있습니다.
mysite/ 디렉토리 내부에는 프로젝트를 위한 실제 Python 패키지들이 저장됩니다. 이 디렉토리 내의 이름을 이용하여, (mysite.urls 와 같은 식으로) 프로젝트의 어디서나 Python 패키지들을 임포트할 수 있습니다.
mysite/__init__.py
: Python으로 하여금 이 디렉토리를 패키지처럼 다루라고 알려주는 용도의 단순한 빈 파일입니다. Python 초심자라면, Python 공식 홈페이지의 패키지를 읽어보세요.
mysite/settings.py: 현재 Django 프로젝트의 환경 및 구성을 저장합니다. Django settings에서 환경 설정이 어떻게 동작하는지 확인할 수 있습니다.
mysite/urls.py: 현재 Django project 의 URL 선언을 저장합니다. Django 로 작성된 사이트의 《목차》 라고 할 수 있습니다. URL dispatcher 에서 URL 에 대한 자세한 내용을 읽어보세요.
mysite/asgi.py: An entry-point for ASGI-compatible web servers to serve your project. See ASGI를 사용하여 배포하는 방법 for more details.
mysite/wsgi.py: 현재 프로젝트를 서비스하기 위한 WSGI 호환 웹 서버의 진입점입니다. WSGI를 사용하여 배포하는 방법를 읽어보세요.
1) Django는 사용할 루트 URLconf 모듈을 결정합니다. 일반적으로 이것은 ROOT_URLCONF설정 값 이지만 들어오는 HttpRequest개체에 urlconf 속성(미들웨어로 설정)이 있는 경우 해당 값이 ROOT_URLCONF설정 대신 사용됩니다.
2) Django는 해당 Python 모듈을 로드하고 변수를 찾습니다. This should be a sequence of django.urls.path() and/or django.urls.re_path() instances.
3) Django는 각 URL 패턴을 순서대로 실행하고 요청된 URL과 일치하는 첫 번째 패턴에서 중지하고 path_info와 맞춰서 대조해본다.
4) Once one of the URL patterns matches, Django imports and calls the given view, which is a Python function (or a class-based view). The view gets passed the following arguments:
5) If no URL pattern matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view. See Error handling below.
python manage.py runserver
로 런타임 서버를 러닝할 수 있다. python manage.py runserver 8080
python manage.py startapp polls
을 통해서 polls APP을 추가해줄 수 있다. from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
include() 함수는 다른 URLconf들을 참조할 수 있도록 도와줍니다. Django가 함수 include()를 만나게 되면, URL의 그 시점까지 일치하는 부분을 잘라내고, 남은 문자열 부분을 후속 처리를 위해 include 된 URLconf로 전달합니다.
include()에 숨은 아이디어 덕분에 URL을 쉽게 연결할 수 있습니다. polls 앱에 그 자체의 URLconf(polls/urls.py)가 존재하는 한, 《/polls/》, 또는 《/fun_polls/》, 《/content/polls/》와 같은 경로, 또는 그 어떤 다른 root 경로에 연결하더라도, 앱은 여전히 잘 동작할 것입니다. 다른 URL 패턴을 포함할 때마다 항상 include()를 사용해야 합니다. admin.site.urls가 유일한 예외입니다.
이제 서버를 다시 시작하고, 아래 사진과 같이 뜨면 첫번째 뷰 성공!
path()
인수route 는 URL 패턴을 가진 문자열 입니다. 요청이 처리될 때, Django 는 urlpatterns 의 첫 번째 패턴부터 시작하여, 일치하는 패턴을 찾을 때 까지 요청된 URL 을 각 패턴과 리스트의 순서대로 비교합니다.
패턴들은 GET 이나 POST 의 매개 변수들, 혹은 도메인 이름을 검색하지 않습니다. 예를 들어, https://www.example.com/myapp/ 이 요청된 경우, URLconf 는 오직 myapp/ 부분만 바라 봅니다. https://www.example.com/myapp/?page=3, 같은 요청에도, URLconf 는 역시 myapp/ 부분만 신경씁니다.