[ Django 웹 개발 시작하기 ] 2장. Django 구조 이해하기
이 포스트는 코드잇 Django 웹 개발 시작하기 2장 강의을 바탕으로 작성하였습니다 :)
https://www.codeit.kr/topics/getting-started-with-django
Django 웹 개발 시작하기 - Django 강의 | 코드잇
Django는 파이썬을 기반으로 하는 웹 개발 프레임워크입니다. Django에는 회원가입, 로그인, 검색 같이 웹 서비스에서 주로 사용되는 여러 기능들이 이미 만들어져 있어서 원하는 걸 그냥 갖다 쓰면
www.codeit.kr
* WSL 디렉토리 생성 명령어 : mkdir
ex) mkdir codeit-django
* 생성한 디렉토리로 이동 명령어 : cd
* VSCode 서버 설치 or 실행
code .
* pyenv를 이용한 가상환경 생성
pyenv virtualenv {파이썬 버전} {가상 환경 이름}
ex) pyenv virtualenv 3.7.13 django-envs
* pyenv로 생성한 가상 환경 지우기
pyenv uninstall {가상 환경 이름}
ex) pyenv uninstall django-envs
* 가상 환경 global 적용하기
pyenv global {가상 환경 이름}
ex) pyenv global 3.8.13
* 특정 디렉토리에 로컬 가상 환경 적용
pyenv local {가상 환경 이름}
ex) pyenv local django-envs
* django 개발 서버 실행
python manage.py runserver
** Django 프로젝트 (웹 서비스 전체)
1. Django 프로젝트 생성하기
django-admin startproject {프로젝트명}
# 예시
django-admin startproject codeit_proj
2. Django 프로젝트 구조
프로젝트를 생성하면 다음과 같은 구조의 파일들이 생성된다
codeit_proj/ #프로젝트명 [PROJECT ROOT]
manage.py
codeit_proj/ # 프로젝트명 [PROJECT APP]
__init__.py
settings.py
urls.py
wsgi.py
2-1 Project Root
최상위 디렉토리를 "Project Root"라고 하며, 전체 파일이 들어 있는 디렉토리
2-2 manage.py
manage.py는 하나의 Django 프로젝트를 생성하면 자동으로 만들어지는 프로젝트 관리를 위한 명령 유틸리티
django-admin 형태에 생성한 프로젝트에 대해 설정을 해 주는 몇 가지 기능이 더 들어 있는 형태이다
2-3 ProjectApp
Project Root와 동일한 이름의 디렉토리이기에 위 디렉토리를 project app 이라고 지칭
2-4 __init__.py
이 파일이 포함 된 디렉토리를 파이썬의 패키지로 인식하게끔 하기 위해 사용
python 3.3 이후 버전부터는 이 파일이 없어도 패키지로 인식되지만 하위 버전 호환을 위해 작성하는 것이 좋음
2-5 settings.py
Django 프로젝트의 여러 가지 설정을 담고 있는 파일
프로젝트와 앱의 연결을 할 수 있음
새로운 앱을 만들었다면 장고에게 새로운 앱을 만들었다는 사실을 알려주어야 하는데,
이때 이 settings.py 파일을 사용한다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'foods',
]
현재 프로젝트를 구성하고 있는 앱을 리스트로 표현해둔 것을 확인할 수 있다.
새롭게 앱을 생성하면 이 리스트에 앱의 이름을 써주고 항상 끝에 ,(콤마)를 붙여준다.
2-6 urls.py
Django 프로젝트로 돌아온 url (=클라이언트의 요청) 을 보고 알맞은 로직으로 연결해주는 역할을 하는 파일
모든 url에 대해 분기가 끝나면 알맞은 view를 호출하여 로직을 처
2-7 wsgi.py
WSGI는 Webserver Gateway Interface의 약자로 파이썬에서 웹 통신을 하기 위한 일종의 약속
** Django 앱(App) ( 기능을 나타내는 단위 )
1. Project와 App의 차이
서로 다른 기능을 하는 하나의
App1+ App2 + .... => Project
서로 다른 기능을 하는 여러 앱들이 모여 하나의 프로젝트를 이룰 수 있다
2. App 생성하기
python manage.py startapp {생성할 App 이름}
#예시
python manage.py startapp foods
Django에서 앱을 생성할 때 manage.py를 이용
파이썬 파일(.py)을 명령어로 직접 실행 하려면 python {파일이름}.py {인수 목록}을 입력하면 된다
3. Django App 구조
{app_name}/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
foods를 살펴보면 다음과 같은 파일이 자동으로 생성된 것을 확인할 수 있다.
3-1 admin.py
각각의 앱을 Django의 관리자 기능과 연결하거나 관리자 기능에 대해 설정을 하는 파일
3-2 apps.py
각각의 App마다 추가적인 기능 및 설정을 넣어 주기 위한 파일
3-3 migrations 디렉토리
Django 앱의 데이터 구조에 대한 변경 사항인 migration 파일이 저장되는 디렉토리
3-4 models.py
앱에서 사용하는 데이터 구조를 정의하고 데이터베이스와의 소통을 담당하는 파일
3-5 tests.py
앱에 대한 테스트(=Django 프로젝트의 모든 기능이 의도한 대로 잘 작동하는지 체크하는) 코드를 작성하는 파일
3-6 views.py
앱에서 어떤 기능을 할지에 대한 메인 로직을 담당하는 파일
Django 앱의 철학은 'Reusable App'
- 한 가지 앱은 한 가지 기능을 하고, 그 기능을 잘 수행해야 한다
- 장고 개발자는 프로젝트를 많은 앱으로 구성하는 것을 두려워하면 안 된다
- 각각의 앱을 유연하게 작성해야 한다
- 다른 사람에게 배포가 가능하도록 만들어야 한다
** 클라이언트와 서버
1) 클라이언트가 서버로 부터 요청
client 요청 server
웹브라우저 (ex. 크롬) ------------------> django
domain/foods/index
* url
내가 원하는 자원 (ex.웹페이지) 을 찾기 위한 주소
서버에게 자원을 요청하는 일종의 문자열을 의미
도메인(Domain) + 경로(Path) 구조로 이루어짐
ex) bakey.codeit.kt/foods/index
* domain
요청을 처리하는 서버를 찾아주는 역할
ex) bakey.codeit.kr
* 경로
요청하는 내용을 담고 있음
서버 안에서 원하는 것이 있는 위치
ex) /foods/index
클라이언트의 요청에 따라 서버에 있는 장고 프로젝트가 url의 경로와 내부 로직과 매칭시키려고 한다.
(필자는 domain 이름을 costaurant로 두어 진행하겠다)

2) costaurant > settings.py에 있는 ROOT_URLCONF 확인
"ROOT_URLCONF"은 장고가 URL을 보고 가장 먼저 어떤 파일을 봐야 할지 설정하는 부분이다
ROOT_URLCONF = 'costaurant.urls'
이 코드를 통해서 프로젝트 앱인 costaurant의 urls 파일로 이동한다 (costaurant > urls.py)
3) urls.py로 이동한 후 입력된 url 경로와 매치되는 부분을 확인
urlpatterns = [
path('admin/', admin.site.urls),
path('foods/',include('foods.urls'))
]
클라이언트가 요청한 domain/foods/index 부분에서 "foods/"가 매칭된다
-> include('foods.urls') 를 실행 (= foods App 안에 있는 urls 파일을 확인)
(foods > urls.py 으로 이동)
4) foods App 안에서 "index/" 매칭
urlpatterns = [
path('index/',views.index)
]
클라이언트가 요청한 domain/foods/index 부분에서 "index/"가 매칭된다
-> views.index 를 실행 (= foods app 안에 있는 views 파일을 확인)
(foods > views.py 으로 이)
5) 연결된 함수 호출
def index(request):
return HttpResponse("<h2> Hello, Django !</h2>")
views 파일에 있는 index 함수 호출된다
-> <h2> 태그의 내용이 반환
6) 클라이언트로부터 응답

클라이언트가 요청한 url을 입력하면
<h2>태그 내용이 화면에 구현되는 것을 확인할 수 있다
= 서버가 응답을 한 것
cf) 서버의 응답
서버는 웹 페이지 뿐만 아니라 이미지나 동영상 등 여러가지 형태의 자원(Resource)를 클라이언트에게 제공할 수 있음
** Django 템플릿과 렌더링
foods > views.py 에 있는 index 함수에 아래와 같이 여러 개의 html 코드들을 나열한다면
views 파일이 너무 어지럽혀진다.
def index(request):
return HttpResponse('''
<h2> Hello, Django !</h2>
<p> Just Codeit! </p>
<p> Just Codeit! </p>
<p> Just Codeit! </p>
<p> Just Codeit! </p>
''')
이때, 별도의 파일인 "템플릿"을 사용하는 것이 깔끔하다
템플릿 Template
Django에서 html과 같이 화면 구성 담당하는 부분을 의미
1) 템플릿 생성
foods App 디렉토리에에 새로운 디렉토리 templates 생성
--> 그 안에 foods 라는 새로운 디렉토리 생성
--> index.html (=index 템플릿) 생성


2) 템플릿을 rendering
* Template을 Render한다
= Template을 유저에게 보여준다
views.py의 다음과 같은 index 함수에
def index(request):
return HttpResponse('''
<h2> Hello, Django !</h2>
<p> Just Codeit! </p>
<p> Just Codeit! </p>
<p> Just Codeit! </p>
<p> Just Codeit! </p>
''')
render() 함수를 사용하여 수정한다
def index(request):
return render(request,'foods/index.html') # request, 원하는 템플릿 경로
첫번째 파라미터로 request, 두번째 파라미터로 원하는 템플릿의 경로라는 정보를 토대로
Rendering(렌더링)하여 HttpResponse 객체로 변환시켜 응답한다
3) 클라이언트로부터 응답

cf) render() 함수
render 함수는 인자로 넘겨주는 템플릿과 context 데이터를 합쳐서 HttpResponse 객체로 돌려주는 함수이다
# 기본형
render(request,template_name,context=None,content_type=None,status=None,using=None)
이 중에서 필수 인자는 request와 template_name이다.
* request
데이터를 요청한 요청 객체를 넘겨준다.
앞서 보았던 index 함수의 인자로 들어온 request를 render에서도 사용한 것이 이에 대한 예시이다.
def index(request):
return render(request,'foods/index.html') # request, 원하는 템플릿 경로
* template_name
렌더링에서 사용할 대상 템플릿을 명시한다.
ex) 'foods/index.html' <- index 함수에서의 예시
선택 인자에 관한 내용은 아래 render 공식문서를 참고하길 바란다.
https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/#django.shortcuts.render
** Django MVT 아키텍처
1) Model
- 데이터 구조 생성
- 데이터베이스와 소통
여려 정보를 담은 테이블을 모델에 정의한 후 -> 데이터베이스와 소통하며 CRUD 할 수 있다.
2) Template
- 웹 사이트의 화면 구성 담당 -> html, css, js를 이용
- 매번 바뀌는 동적인 화면을 구성 -> template language 이용
3) View
- 웹 사이트의 로직을 담당
- Model과 Template 사이를 연결 (=요청을 처리하는 역할)
[ case 1 ] View - 템플릿

>> 클라이언트로부터 간단한 요청이 들어왔을 때, 템플릿을 바로 렌더링하여 응답을 한다.
[ case 2 ] 모델 - View - 템플릿
step 1. 클라이언트로부터 요청이 들어왔을 때, 모델을 통해서 필요한 데이터를 가져온 다음 데이터를 알맞게 처리한다.

step 2. 처리된 데이터를 템플릿으로 보내 필요한 화면을 렌더링 후 만들어진 HTML 코드로 응답한다.

** MVT 아키텍처 최종 정리
1. Django는 맨 처음 url을 보고 알맞은 메인 로직을 처리하는 View 호출
2. View에서는 필요하다면 model을 통해 데이터베이스와 소통,
주 역할은 처리한 데이터를 화면에 담는 template과 함께 렌더해서 최종화면을 구성하는것
3. 완성된 최종 화면을 view를 통해 클라이언트에게 응답으로 돌려줌