# 2. Web/Django

Django # Django란? MTV패턴이란? DTL이란? URLs 유지보수란?

둥굴둥굴둥굴레차 2021. 3. 8. 22:16

Django란?

  1. Dynamic Web Application Program
  2. Python web framework (python으로 작성된 오픈소스 웹 애플리케이션 프레임워크. )
  3. MVC(Model, View, Controller)패턴을 따르고 있다.

 

Static Web과 Dynamic Web

Static web

미리 저장된 정적파일(HTML, CSS ,JS)을 사용자의 요청이 들어오면 그대로 제공하여 보여주는 것.

 

Dynamic web

사용자의 요청에 따라 server-side에서 처리해준 다음 다른 데이터를 만들어 보여주는 것.

 

따라서, 이러한 Dynamic website를 만들어주는 프레임워크가 Django이다.

 

즉, 이전 HTML, CSS를 배울 땐 client-side에서 보여지는 화면에 집중했다면

이제는 Django를 배우며 해당 요청을 입력받아 응답을 보내주는 서버단을 제작하는데에 집중하게 된다.

 

web framework

웹페이지를 개발하는 과정에서의 기본적인 구조나 필요한 코드들은 알아서 제공해주는 틀이기 때문에
웹페이지 제작시 어려움을 줄여주는 틀이라고 말할 수 있다.

 

Django를 사용하는 기업들

Spotify, Instagram, Dropbox, Delivery Hero 등..

즉, Django는 대규모 서비스에서도 충분히 잘 돌아가는 프레임 워크라는 것을 알 수 있다.

 

django는 파이썬으로 작성된 오픈소스 웹 프레임워크로,
모델-뷰-컨트롤러 모델 패턴을 따르고 있다.

 

MVC란?

소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴

 

이 패턴을 잘 사용하면 사용자 인터페이스로부터 비즈니스 로직을 분리

애플리케이션의 시각적 요소나 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있다.

 

Model : 애플리케이션의 정보(데이터)
View : 텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소
Controller : 데이터와 비즈니스 로직 사이의 상호동작을 관리

 

 

MVC패턴과 Django의 MTV패턴

 

따라서, Django는 MTV패턴을 따른다고 말한다.

 

Model
응용프로그램의 데이터 구조를 정의하고 데이터베이스의 기록을 관리(추가, 수정, 삭제)

Template
파일의 구조나 레이아웃을 정의
실제 내용을 보여주는 데 사용 (presentation)

View
HTTP 요청을 수신하고 HTTP 응답을 반환
Model을 통해 요청을 충족시키는데 필요한 데이터에 접근
그리고 탬플릿에게 응답의 서식 설정을 맡김

 

Internationalization

# settings.py

LANGUAGE_CODE = 'ko-kr'

TIME_ZONE = 'Asia/Seoul'

 

 

.py 3대장 기억하기

1. urls.py : 주소(URL) 관리

2. views.py : 페이지 관리 (페이지 하나 당, 하나의 함수)

3. models.py : 데이터베이스 관리

 

 


 

Django 시작

 

Django 설치

$ pip install django

 

특정 버전 설치

$ pip install django==x.x.x


설치 확인

$ pip list
# python -m django --version

 

프로젝트 생성

$ django-admin startproject first_project

 

서버 실행

$ python manage.py runserver

 

 

Application 생성

$ python manage.py startapp articles

 

Application 등록

방금 생성한 app을 사용하려면 프로젝트에 등록 해야 한다.

# settings.py

INSTALLED_APPS = [
	'articles',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 

[참고] INSTALLED_APPS의 app order

INSTALLED_APPS = [
    # Local apps
    'blogs',

    # Third party apps
    'haystack',

    # Django apps
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
]

 


 

Template

DTL (Django Template Language)

조건, 반복, 변수치환, 필터 등의 기능을 제공
단순히 python이 HTML에 포함된 것을 넘어서 프레젠테이션을 표현한 것
파이썬처럼 일부 프로그래밍 구조(if, for등)을 사용할 수 있지만 해당 python코드로 실행되는 것은 아님

 

DTL Syntax

1. Variable  {{ variables }}

    - dot(.)를 사용하여 변수 속성에 접근

2. Filters  {{ variable|filter }}

    - 파이프(|)를 사용하여 적용

3. Tags  {% tag %}

    - 일부 태그는 시작과 종료 태그가 필요 ({% tag %} ... {% endtag %})

4. Comments  {# lorem #}

 

Template inheritance

템플릿 상속은 기본적으로 코드의 재사용성에 초점을 맞춤
템플릿 상속을 사용하면 사이트의 모든 공통 요소를 포함하고, 하위 템플릿이 재정의(override) 할 수있는 블록을 정의하는 기본 “skeleton” 템플릿을 만들 수 있음

# settings.py

TEMPLATES = [
    {
        ...,
        'DIRS': [BASE_DIR / 'firstpjt' / 'templates'],
...
]

app_name/templates 디렉토리 외 추가 경로 설정

 

extends tag

자식(하위)템플릿이 부모 템플릿을 확장한다는 것을 알림
반드시 템플릿 최상단에 위치해야 함(== 템플릿의 첫번째 템플릿 태그여야 함)

즉, 2개 이상 사용할 수 없음

 

block tag

하위 템플릿에서 재지정(overriden)할 수 있는 블록을 정의
하위 템플릿이 채울 수 있는 공간
가독성을 높이기 위해 선택적으로 {% endblock %} 태그에 이름 지정

{% block content %}
{% endblock content %}

 

HTML Form

HTML <form> element

웹에서 사용자 정보를 받아오는 여러 방식

(text, button, checkbox, file, hidden, image, password, radio, reset, submit)을 제공하고,

사용자로부터 할당된 데이터를 서버로 전송하는 역할을 담당

 

핵심 속성

action : 입력 데이터가 전송될 URL 지정
method : 입력 데이터 전달 방식 지정

 

HTML <input> element

사용자로부터 데이터를 입력 받기 위해 사용

type 속성에 따라 동작 방식이 달라짐

 

핵심 속성

name
 - 중복 가능, 양식을 제출했을 때 name이라는 이름에 설정된 값을 넘겨서 값을 가져올 수 있음
 - 주요 용도는 GET/POST 방식으로

   서버에 전달하는 파라미터(name 은 key , value 는 value)로 ?key=value&key=value 형태로 전달

 

HTTP request methods


HTTP

HTML 문서와 같은 리소스들을 가져올 수 있도록 해주는 프로토콜(규칙, 규약)
웹에서 이루어지는 모든 데이터 교환의 기초
HTTP는 주어진 리소스가 수행 할 원하는 작업을 나타내는 request methods를 정의


GET

서버로부터 정보를 조회하는 데 사용
데이터를 가져올 때만 사용해야 함
데이터를 서버로 전송할 때 body가 아닌 Query String Parameters를 통해 전송

 


 

[실습] throw & catch

throw

# first_project/urls.py

path('throw/', views.throw),
# articles/views.py 

def throw(request):
    return render(request, 'throw.html')
<!-- articles/templates/throw.html -->

<form action="/catch/" method="GET">
  <label for="message">Throw</label>
  <input type="text" id="message" name="message">
  <input type="submit">
</form>

 

catch

# first_project/urls.py

path('catch/', views.catch),
# articles/views.py

def catch(request):
    message = request.GET.get('message')
    context = {
        'message': message,
    }
    return render(request, 'catch.html', context)
<!-- articles/templates/catch.html -->

<h1>너가 던져서 내가 받은건 {{ message }}야!</h1>
<a href="/throw/">뒤로</a>

 

URLs 유지보수

App URL mapping

하나의 프로젝트의 여러 앱이 존재한다면, 각각의 앱 안에 urls.py을 만들고

urls.py에서 각 앱의 urls.py 파일로 URL 매핑을 위탁하게 가능

 

두번째 app 생성 및 등록

$ python manage.py startapp pages
INSTALLED_APPS = [
    'articles',
    'pages',
    ...,
]
# articles/urls.py

from django.urls import path
# django는 명시적 상대경로(from .module import ..)를 권장한다.
from . import views 


urlpatterns = [
    path('index/', views.index),
    path('greeting/', views.greeting),
    path('dinner/', views.dinner),
    path('throw/', views.throw),
    path('catch/', views.catch),
    path('hello/<str:name>/', views.hello),
]
# pages/urls.py

from django.urls import path

##[주의] 
# urlpatterns list가 없는 경우 에러가 발생한다. 
# 아래와 같이 빈 리스트로서라도 적어줘야 한다.
urlpatterns = [

]

Including other URLconfs

include()

다른 URLconf(app1/urls.py)들을 참조할 수 있도록 도움

함수 include()를 만나게 되면, URL의 그 시점까지 일치하는 부분을 잘라내고, 

남은 문자열 부분을 후속 처리를 위해 include된 URLconf로 전달

# firstpjt/urls.py

from django.contrib import admin
from django.urls import path, include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('articles/', include('articles.urls')),
    path('pages/', include('pages.urls')),
]

 

Naming URL patterns

Django는 URL에 name을 지정하는 방법을 제공하므로써 뷰 함수와 템플릿에서 특정 주소를 쉽게 참조할 수 있도록 도움

# articles/urls.py

urlpatterns = [
    path('index/', views.index, name='index'),
    path('greeting/', views.greeting, name='greeting'),
    path('dinner/', views.dinner, name='dinner'),
    path('throw/', views.throw, name='throw'),
    path('catch/', views.catch, name='catch'),
    path('hello/<str:name>/', views.hello, name='hello'),
]

 

url tag 사용하기

<!-- index.html -->

{% extends 'base.html' %}

{% block content %}
  <h1>만나서 반가워요!</h1>
  <a href="{% url 'greeting' %}">greeting</a>
  <a href="{% url 'dinner' %}">dinner</a>
  <a href="{% url 'throw' %}">throw</a>
{% endblock %}

 

{$ url '' %}

주어진 URL 패턴 이름 및 선택적 매개 변수와 일치하는 절대 경로 주소를 반환
템플릿에 URL을 하드 코딩하지 않고도 DRY 원칙을 위반하지 않고 링크를 출력하는 방법

 

Variable routing 동적 라우팅

주소 자체를 변수처럼 사용해서 동적으로 주소를 만드는 것

# urls.py

urlpatterns = [
    ...,
    # path('hello/<name>/', views.hello),
    path('hello/<str:name>/', views.hello),
]
# views.py

def hello(request, name):
    context = {
        'name': name,
    }
    return render(request, 'hello.html', context)
<!-- hello.html -->

{% extends 'base.html' %}

{% block content %}
  <h1>만나서 반가워요 {{ name }}님!</h1>
{% endblock %}

 

URL namespace

app_name 작성

# pages/urls.py

app_name = 'pages'
urlpatterns = [
    path('index/', views.index, name='index'),
]
# articles/urls.py

app_name = 'articles'
urlpatterns = [
    ...,
]

 

app_name 속성

 - URL namespace를 사용하면 서로 다른 앱에서 동일한 URL 이름을 사용하는 경우에도

   이름이 지정된 URL을 고유하게 사용 할 수 있음

 - urls.py에 app_name attribute 값 작성

 

[참조]

: 를 사용하여 지정

예를들어, app_name이 articles이고 URL name이 index인 주소 참조는 articles:index

 

URL tag 변경

<!-- articles/templates/index.html -->

{% extends 'base.html' %}

{% block content %}
  <h1>만나서 반가워요!</h1>
  <a href="{% url 'articles:greeting' %}">greeting</a>
  <a href="{% url 'articles:dinner' %}">dinner</a>
  <a href="{% url 'articles:throw' %}">throw</a>

  <h2><a href="{% url 'pages:index' %}">두번째 앱 index로 이동</a></h2>
{% endblock %}

 

Template namespace


Django는 기본적으로 app_name/templates/ 경로에 있는 templates 파일들만 찾을 수 있으며,

INSTALLED_APPS에 작성한 app 순서로 tamplate을 검색 후 렌더링!


임의로 templates의 폴더 구조를 app_name/templates/app_name 형태로 변경해 

임의로 이름 공간 생성 후 변경된 추가 경로 작성

# articles/views.py

return render(request, 'articles/index.html')
# pages/views.py

return render(request, 'pages/index.html')