Django

python 기반 웹 프레임워크

 

 

Flask vs Django

  • Flask
    • "마이크로"웹 프레임워크 (최소한의 기능을 갖춤)
    • 사용자가 모듈을 추가하면서 웹을 완성
    • 간단한 프로젝트에 적합
  • Django
    • 거의 모든 것들이 내장되어 있음
    • 큰 프로젝트에 적합

 

 

 

 


Django 시작

가상환경 구축하기

# 파이썬 가상환경 모듈 설치
(base) $ pip install virtualenv

# 현재 디렉토리에 새 virtualenv 가상환경 만들기
(base) $ virtualenv <가상환경 이름>

# 가상환경 실행
(base) $ ./venv/Scripe/activate

 

 

Django 설치하기

(venv) $  pip install django

 

 

Django 프로젝트 생성

(venv) $ django-admin startproject <project_name>

django-admin startproject webproj 생성

 

 

Django App 서버시작

# 현재 디렉토리에 manage.py 파일이 있는지 확인
(venv) $ python manage.py runserver

 

 

 


Django 기본요소

  • __init()__.py : 파이썬 모듈로써 인식하게 해주는 역할
  • asgi.py, wsgi.py : 서버에서 Django 프로젝트를 가동할 때 다루게 될 부분
  • settings.py : 전반적인 Django 프로젝트의 설정사항을 반영
    • BASE_DIR, SECRET_KEY, DEBUG, ALLOWED_HOSTS, INSTALLED_APPS, MIDDLEWARE
    • ROOT_URLCONF : 프로적트의 url을 관리할 모듈 지정
    • TEMPLATES
    • WSGI_APPLICATION : 파이썬에서 웹서버와 소통하는데 필요한 어플리케이션 담당
    • DATABASES, AUTH_PASSWORD_VALIDATORS
    • LANGUAGE_CODE, TIME_ZOEN, USE_I18N, USE_L10N, USE_TZ
    • STATIC_URL
      \( \Rightarrow \) 이미 많은 기능들이 내장되어 있음
  • urls.py : url 관리

 

 

 

 

Django 프로젝트에서의 App

한 project는 여러가지 App으로 구성

App 각각은 특정 명령을 수행하는 view와 template의 집합이다. (모듈화)
따라서 우리는 각 App을 독립적으로 개발할 수 있다.

ex)
project : naver
app_1 : blog
app_2 : cafe
app_3 : sports

 

 

 

 

 


Django App 시작

Django App 생성

(venv) $ django-admin startapp <app_name>

django-admin startapp homepage 생성

 

 

 

Django App 기본 구성요소

  • admin.py : 기본적으로 제공되는 admin page 설정 관리
  • apps.py : App에 대한 설정 관리
  • model.py : App 내에서 쓰일 스키마를 클래스 형태로 작성
  • views.py : App 내에서 다룰 뷰 관리

 

 

 

 


Django의 MTV 패턴

디자인 패턴이란?

  • 코드의 모듈화를 이용해서 각 코드가 독립적으로 동작해서 유기적으로 우리가 원하는 목표를 달성할 수 있게 해준다.
  • 대표적으로 MVC 패턴(Model, View, Controller) 이 있다.

Django에서는 MVT 사용

  • Model
  • view
  • Template

 

 

 


index view 작성

  • views.py
from django.shortcuts import HttpResponse, render

# Create your views here.
def index(request):
    return HttpResponse("Hellow world!")  # Http에 응답을 줄 수 있는 함수 사용
    # 어느 경로로 들어왔을 때 index 함수를 실행하는지 설정해주는 부분은 ../webproj/urls.py에 관리

프로젝트 디렉토리에 urls.py 파일이 있지만
각 App에 urls.py 파일을 따로 두어 관리하는 것이 좀 더 편하다

 

 

  • webproj/urls.py
from django.contrib import admin
from django.urls import path

# 현재 urls.py에는 /homepage/views.py에 대한 정보가 없다.
# 따라서 우리는 이 파일에 정보를 불러오기 위해 import하여 사용
from homepage.views import index


# path는 두 가지 인자가 필요 (경로, 그에 해당하는 것)
urlpatterns = [
    path('', index),  # 127.0.0.1/  # ''경로로 들어왔을 때 homepage.views/index를 실행해라
    path('admin/', admin.site.urls),  # 127.0.0.1/admin
]

 

 

  • webproj/settings.py
... 

INSTALLED_APPS = [ 
	..., 
    'homepage', # homepage를 app으로 인식하기 위해 추가하는 코드 
]

 

 

 

 

 


 

admin page 로그인

  • Django에서는 다음과 같이 admin, auth, contenttypes, sessions App이 기본적으로 생성되어 있다.
  • 따라서 먼저 위의 4개의 App에 대한 마이그레이션을 진행하여 DB에 반영해줘야 한다.
  • 마이그레이션을 진행하면서 auth_user 테이블이 생성됨
python manage.py migrate

 

 

슈퍼유저 생성

python manage.py createsuperuser

 

 

  • 테이블 확인 가능 ( Groups 와 Users 라는 기본 테이블 존재 )
  • 데이터베이스 관리 가능 ( CRUD 가능 )

 

 

 


Template으로 보여줄 화면 구성하기

  • homepage/views.py
    def index(request):
      return HttpResponse("<h1>Hello World!</h1>")

지금은 단순한 문자열을 반환하여 확인하기 위해 위와 같이 간단하게 작성하였다.

하지만 단순한 문자열이 아닌 긴 내용의 html 코드를 반환해주려면 어떻게 해야할까?

 

\(\Rightarrow \) render() 함수를 이용!

 

 

 


render()의 파라미터

  • request
  • template_name : html 파일 이름
  • context : template에 전달해줄 변수 (dict 형)

 

  • homepage/templates/index.html - template 폴더 생성
<!DOCTYPE html> 
<html> 
  <head> 
  	<title>Python django example</title> 
  </head> 

  <body> 
    <h1>Title</h1> 
    <p>blah blah blah</p> 
  </body> 
</html>

 

 

  • homepage/views.py
def index(request): 
	return render(request, 'index.html', {})

 

  • webproj/setting.py
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

...

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
        	# homepage/template 위치를 지정해줘야한다.
            os.path.join(BASE_DIR, 'homepage', 'template'), # or BASE_DIR + 'hompage/template/index.html 
            ],  
        
        ...
]

 

 


Template 언어

 

render()의 context 파라미터를 이용하여 view에서 template으로 값 넘겨주기

 

1. 템플릿 변수 `{{}}`

  • homepage/views.py
def index(request):
    number = 10
    return render(request, 'index.html', {"my_num": number})

 

 

  • homepage/template/index.html
<!DOCTYPE html>
<html>
<head>
    <title>Python django example</title>
</head>
<body>
    <h1>Title</h1>
    <p>blah blah blah</p>
    <p>{{ my_num }}</p>
</body>
</html>

 

 

 


2. 템플릿 필터 `{{ key | 필터 함수 }}` 

  • homepage/views.py
def index(request): 
	name = 'Micheal 
    return render(request, 'index.html', {'my_name' : name })

 

 

 

  • homepage/template/index.html
<!DOCTYPE html>
<html>
<head>
    <title>Python django example</title>
</head>
<body>
    <h1>Title</h1>
    <p>blah blah blah</p>
    <p>{{ my_name | length }}</p>
    <p>{{ my_name | upper }}</p>
</body>
</html>

 

 

 

 


3. 템플릿 태그  `{% tag ... %} ~ {% endtag %}`

 

  • homepage/views.py
def index(request): 
	nums = [1,2,3,4,5] 
    return render(request, 'index.html', {'my_list' : num })

 

  • homepage/template/index.html
<!DOCTYPE html>

<html>
  <head> 
  	<title>Python django example</title>
  </head>

  <body>
    <h1> Title </h1>
    <p> blah blah blah</p>

    {% for element in my_list %}
      {% if not element|divisibleby:"2"  %}
      	<p>{{ element }}</p>
      {% endif %}
    {% endfor %}
  </body>
</html>