django 1

s2ul3·2022년 10월 20일
0

웹 프레임워크 : Flask, django

1. django 시작하기

  • Python 기반 웹 프레임워크
  • django vs Flask
    • flask : "마이크로" 웹 프레임워크 (즉 최소한의 기능을 지님 + 추가적인 기능을 붙여가면서 사용), 작은 프로젝트에 적합
    • django : 이미 모든 기능이 내장되어 있음, 큰 프로젝트에 적합

django 설치하기

  • 가상환경 생성
    virtualenv 이름
    ex) virtualenv venv

  • 가상환경 사용하기 (윈도우 기준)
    .\venv\Scripts\activate.bat
    --> 결과

    위와 같이 앞에 (venv)가 붙게됨. -> 가상환경에 잘 들어왔음.

  • django 설치
    pip install django

  • 가상환경 내 모듈 확인하기
    pip freeze : 처음에 가상환경을 사용할 때 모듈은 아무것도 없음

  • 장고 프로젝트 시작
    django-admin startproject <proj_name>
    ex) django-admin startproject webproj : 프로젝트 이름은 webproj로 설정

    장고 프로젝트가 잘 생성 되었음을 확인할 수 있음.

  • 생성된 프로젝트로 이동해보면 다음과 같이 두개의 파일 존재.

    • manage.py --> 이 파일을 사용하여 서버를 가동할 수 있음.
    • webproj (프로젝트 이름 파일)
  • manage.py 파일로 서버 가동하기
    python manage.py runserver

    위 결과처럼 서버 http://127.0.0.1:8000/ 가 가동이 된다.

2. django의 구성 요소

  • manage.py : 장고를 실행하는 부분. python manage.py runserver을 통해 실행.
  • __init__.py : 이 디렉토리가 파이썬 모듈로써 인식되도록 하는 역할을 한다.
  • asgi.py, wsgi.py : 서버에서 장고 프로젝트를 가동할 때 쓰게 된다.
  • settings.py : 전반적인 파이썬 장고 프로젝트의 설정사항을 반영하는 파일이다. 많은 기능이 내장되어 있음.
  • urls.py : url을 관리하는 곳이다.

django project and app

  • 하나의 Project는 여러 App으로 구성되어있다.

    • App : 특정 기능(명령)을 수행하는 view, template 등의 모음
      한 사이트에 여러 기능들이 있는 페이지가 존재하므로 각 기능들에 대해서 모듈화를 하여 개별적으로 진행할 수 있다.

    --> 그렇다면 App은 어떻게 만들까?
    먼저 manage.py와 같은 경로에 있는지 확인.

    • 홈페이지를 보여주는 app을 만들어보자!
      django-admin startapp homepage : homepage라는 app을 만들어보자.

--> 그 결과, homepage 디렉토리 안에 다음과 같은 파일들이 생성됨.

  • admin.py
  • apps.py : app에 대한 설정 관리
  • models.py : homepage 모듈 안에서 쓰일 데이터 스키마 등을 클래스 형태로 작성
  • test.py
  • view.py : homepage라는 앱에서 view를 어떻게 관리할 것인지.

django의 MVT Pattern

  1. 유저가 Django에게 HTTP request를 보냄.
  2. Django,즉 서버는 URL에서 urls.py로 url을 인식한다.
  • 만약 들어온 경로가 urls.py에 있다면 이를 View에 보낸다. views.py라는 파일에서 들어온 요청을 처리하게 된다.
    3-a. 데이터베이스를 처리하게 되는 경우 Model에서 데이터베이스를 처리하게 된다.
  • 장고의 경우 데이터베이스를 ORM 구조로 관리한다.
    3-b. 요청에 응답하기 위해 특정 웹페이지를 보여줘야 한다면, Template 에서 .html파일을 통해 처리를 한다.
  • html에서 template 언어를 통해 view 단에서 처리한 변수를 처리할 수 있다.
  1. view와 model 혹은 view와 template이 상호작용이 끝난 후 이 결과는 다시 Django로 거쳐 User에게 보여준다.

2. View로 Request Handling 하기

from django.shortcuts import HttpResponse, render

# Create your views here.

# 어떤 request가 들어왔을 때 Hello World response 주는 view를 만듦
def index(request): # request를 인자로 넣는다.
    return HttpResponse('Hello World') # http response

그렇다면 어느 경로로 이 요청이 들어오면 이 index 함수를 실행할 것인가?
--> urls.py에서 처리한다. (webproj 폴더 안에 들어있음.)
path에 경로를 추가하여 앞서 생성한 view가 실행될 url을 지정해준다.

from django.contrib import admin
from django.urls import path
from homepage.views import index # homepage의 views에 있는 index 함수를 불러옴

urlpatterns = [
    path('', index), # '' : 경로를 지정 안함, 즉 127.0.0.1/ 의 요청이 주어질 때 index함수를 실행하라
    path('admin/', admin.site.urls), # 127.0.0.1/admin/ 요청이 들어올 때 할 행동
]

그 다음 webproj에 있는 settings.py 파일을 연다.
homepage app을 사용하려면 INSTALLED_APPS 인자에 homepage를 추가해야한다. 추가 안하게 되면 장고 프로젝트가 homepage를 app으로 인식 못함.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'homepage' # homepage app을 사용하려면 INSTALLED_APPS 인자에 homepage를 추가해야한다. 
]

설정을 다 했으니 이제 서버를 실행시켜보자.
manage.py가 있는 경로에서 python manage.py runserver 실행.
-> http://127.0.0.1:8000/ 를 다시 들어가보면 다음과 같은 결과가 나옴.

  • 동작 원리
  1. 클라이언트가 127.0.0.1이라는 주소에 요청을 보낸다
  2. urls.py 파일 내 urlpattenrs에 해당 url이 있는지 확인한다.
    path('', index) 코드로 인해 index를 실행하게 된다.
  3. views.py에서 index함수를 실행한다. 즉, HttpResponse인 “Hello World!”를 사용자에게 response한다.

장고는 기본적으로 어드민 페이지(관리자 페이지)를 제공한다.
127.0.0.1/admin/으로 접속하면 다음과 같이 뜸.

이는 관리자 페이지로 접근할 수 있는 로그인 창임. 관리자 페이지에서 앱, 데이터베이스 관리들을 할 수 있다.
로그인 하려면 먼저 관리자 계정을 만들어야함.(CLI 환경에서 진행)

python manage.py migrate
python manage.py createsuperuser


위 4가지 항목 채우기

다시 관리자 페이지 127.0.0.1/admin/으로 접속하여 Username과 Password를 입력한다.

다음과 같은 admin 사이트가 나온다.

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

views.py의 index함수에 다음을 추가.

def index(request):
    return render(request, 'index.html', {})

HttpResponse에는 html이라는 마크업 문서를 작성할 수 있다.
html문서를 따로 관리해줄 수 있는 함수인 render라는 함수를 추가해준다. render는 세가지 파라미터를 갖는데,

  • 첫번째 파라미터 : index 함수의 인자인 http request
  • 두번째 파라미터 : response할 때 보여줄 파일이름
  • 세번째 파라미터 : request와 .html을 처리하는 과정에서 사용할 인자들(데이터)을 딕셔너리 형태로 전달

html을 관리하는 방법은 여러가지가 있는데, 각 앱의 디렉토리에서 관리하는 것을 해보자. (앱의 목적에 따라 디렉토리 구조는 계속 바뀔 수 있다, 이것은 하나의 예시)

  1. homepage 앱에 새로운 디렉토리(folder) 생성 (이름은 template으로 지정)

  2. template의 하위에 index.html이라는 새로운 파일 생성

  3. index.html에 html 형식에 맞게 작성

  • : 가장 최근의 html5 문서임을 강조하기 위해 코드 최상단에 작성.
  • HTML 문법 : 열린 태그 <...> 와 닫힌 태그 </...>로 이루어짐. 그리고 이 태그 사이에 내용을 적는다.
  • 코드의 시작과 끝에 열린태그 < html >와 닫힌태그 < /html >를 작성
  • html은 크게 < head >와 < body >로 이루어져있다.
    • < head > : html파일에 대한 메타적인 정보, 즉 우리가 직접적으로 보는 부분이 아니라 그 뒤에서 이루어지는 부분을 주로 작성.
      • < title > : 문서의 title
    • < body > : html을 구성하는 실제 요소, 즉 사용자가 직접 눈으로 확인하는 요소를 작성.
      • < h1 > : 마크다운에서 header 태그
      • < p > : paragraph, 문단 태그
<!DOCTYPE html>
<html>
    <head>
        <title>Python django example</title>
    </head>

    <body>
        <h1>Title</h1>
        <p>blah blah blah...</p>
    </body>
</html>
  1. 이제 template파일이 어디에 있는지 명시해줘야 한다.
    settings.py의 TEMPLATES의 'DIRS'에 template이 담긴 위치를 지정해줄 수 있는데,
    단순히 'DIRS': ['homepage/template/index.html'],이와 같이 적어준다면 문제가 발생할 수 있다.
    why? webproj 전체 폴더가 이 컴퓨터상의 어디에 있는지 장고는 알 수 없다.
    대신 BASE_DIR 이 변수는 우리 프로젝트의 파일들이 컴퓨터의 어디에 존재하는지 알려준다. 따라서 BASE_DIR을 사용하여 다음과 같이 적어줄 수 있다.
    'DIRS': [BASE_DIR + 'homepage/template/index.html'],
    이렇게도 적을 수 있지만 os.path.join 함수를 이용하여 작성해보자
    os.path.join 함수를 사용하면 슬래시(/)를 쓸 필요 없다.
'DIRS': [
    os.path.join(BASE_DIR, "homepage", "template"),
    ],

정리하자면 우리는 총 3가지 작업을 해줘야 했다.
1. request에서 보여줄 화면을 template 파일 아래 index.html을 만들어 구성
2. view에서 index.html파일을 렌더함수의 인자로써 전달
3. settings에서 TEMPLATES의 디렉토리 값으로 template 전달

이제 뷰에서 딕셔너리를 전달하는 부분(즉 render의 세번째 인자)을 바꿔보자.
rendering은 단순히 어떤 내용을 보여주기보다는 어떤 데이터를 바탕으로 html안의 내용을 완성한다는 의미에 가깝다.
따라서 딕셔너리(render의 세번째 인자)에 자료를 전달해줌으로써 안에 있는 데이터와 html을 합쳐 통합적인 템플릿을 완성.
views.py의 index함수를 다음과 같이 수정한다.

def index(request):
    number = 10
    return render(request, 'index.html', {"my_num" : number})

이제 key값인 my_num을 index.html에서 사용할 것인데, 이를 사용하기 위해 장고 템플릿 언어를 사용한다. 장고 템플릿 언어는 html에서 부가적으로 사용할 수 있는 문법
{{my_num}} : my_num데이터가 주어지면 my_num에 해당하는 정보를 출력하게됨.
즉 템플릿을 만들 때 외부로부터 데이터가 필요한 경우 딕셔너리 형태로 값을 전달해주고 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>

이제, 템플릿 변수에 적용할 수 있는 템플릿 필터에 대해 알아보자.
템플릿 필터는 변수의 값을 특정 형식으로 변환하는 데 사용한다.
예를 들어, 어떤 값이 있을 때 그 값의 길이나 그 값에 대해 특정한 값만 원할 때 템플릿 필터를 사용할 수 있다.
views.py를 다음과 같이 바꿔보자.

def index(request):
    name = "Michael"
    return render(request, 'index.html', {"my_name" : name})

index.html도 마찬가지로 바꿔줌
{{ my_name }}

이 템플릿 변수에 템플릿 필터를 적용해보자.
템플릿 필터는 기본적으로 파이프라인 기호(|)를 사용한다.
ex) {{ my_name|length }} : my_name 값에 length 필터 적용. my_name의 길이를 반환해준다.
ex) {{ my_name|upper }} : my_name 값을 대문자로 바꿔줌.
index.html의 템플릿 변수를 이처럼 수정해주면 결과는 다음과 같다.

이제 템플릿 태그에 대해 알아보도록 하자.
html 파일자체에는 어떤 프로그래밍적 로직을 도입할 수는 없다. (if나 for 등등)
하지만 장고를 사용하는 과정에서는 장고 템플릿 언어라는 것을 사용할 수 있었고,
여기서는 “템플릿 태그”라는 것을 사용할 수 있다.
탬플릿 태그는 {% tag ... %} 와 같은 형식으로 작성
어떠한 태그는 태그를 닫아줘야 하는 형태도 존재한다.
즉 태그와 endtag 사이에 어떤 로직을 집어넣을 수 있다.
템플릿 태그도 종류가 굉장히 다양해서 도큐먼트를 통해 원하는 태그를 찾아 쓰면 된다. 여기서는 가장 많이 사용하는 for 태그와 if 태그를 알아보자.

for 태그는 파이썬에서 사용했던 for문을 html에서도 사용할 수 있게 해준다.
{% for a in b %} 형태
우선 views.py에서 index함수를 수정해 숫자 리스트를 만들자.

def index(request):
    nums = [1, 2, 3, 4, 5]
    return render(request, 'index.html', {"my_list" : nums})

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 %}
            <p>{{ element }}</p> # 태그와 end 태그 사이에 적는 로직내용
        {% endfor %}  # for 태그 끝나는 지점
    </body>
</html>

이제 if태그에 대해 알아보자.
if 태그의 경우 조건에 따라 랜더링해줄 html부분이 달라질 때 사용한다.
ex) my_list의 숫자 중에서 element가 홀수인 경우만 출력해보자.

if 태그의 경우, 템플릿 필터를 이용해 조건을 걸어줄 수 있다.

element 중 홀수만 출력하려면, element가 어떤것으로 나눠떨어지는지 체크해야한다. 이때 사용하는 필터가 divisibleby이다.
템플릿 필터에도 콜론(:)을 통해 파라미터를 전달할 수 있다.
if element|divisibleby:2
콜론 뒤에 “2”라고 쓰면 파라미터 2가 전달되어 element가 숫자 2로 나눠 떨어지게하는 조건을 쓸 수 있다.
홀수만 출력하기 위해서는 위의 조건을 부정하는 element만 출력하면 된다. 따라서 다음과 같이 not을 붙여준다.
if not element|divisibleby:2

<!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" %} # my_list에 원소 하나하나에 대해 로직을 진행하는데 만일 element가 2로 나눠 떨어지지 않으면 다음을 출력
                <p>{{ element }}</p> # 태그와 end 태그 사이에 적는 로직내용
            {% endif%}
        {% endfor %}  # for 태그 끝나는 지점
    </body>
</html>


위와 같이 홀수만 출력했다.

view를 응답하는 과정에서 특정 문서를 보여주고 싶을 때 이것을 지정하는 것을 templete (html문서)가 있었다.
그 과정에서 템플릿 언어, 템플릿 변수, 템플릿 태그, 템플릿 필터를 사용해보았다.

profile
statistics & computer science

0개의 댓글