Framework/Django

[ Django 웹 개발 시작하기 ] 2장. Django 구조 이해하기

yangheeb 2024. 1. 5. 13:13

 

이 포스트는 코드잇 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 템플릿) 생성

 

다음과 같은 경로로

 

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)

 

이 중에서 필수 인자requesttemplate_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를 통해 클라이언트에게 응답으로 돌려줌