Django Basics

지니🧸·2022년 10월 16일
0

Django

목록 보기
1/9
post-thumbnail

Django Basics

Make directory (ex) codeit-django

mkdir codeit-django

특정 디렉토리에 로컬 가상 환경 적용

pyenv local {가상환경 이름}

설치된 장고 버전 확인

django-admin --version

장고 프로젝트 생성

django-admin startproject {프로젝트 이름}

장고 개발 서버 실행

python manage.py runserver

list files

ls

Django 프로젝트 구조

  • Project root: 장고 프로젝트의 모든 파일이 담겨 있는 최상위 디렉토리
    • 이름을 마음대로 바꿔도 영향 X
  • Project app: 프로젝트의 가장 중심이 되는 App
    • root와 이름이 같음
    • 이름을 바꾸면 많은 수정을 해야함
  • manage.py : 프로젝트의 매니저
    • Django 프로젝트 관리를 위한 명령어를 지원
    • 앱 생성, 데이터베이스 관련 명령, 개발서버 실행 등
  • db.sqlite3 : 프로젝트에서 사용하는 데이터베이스 파일
  • Project App 내부
    • init.py : 이 파일이 있는 디렉토리를 하나의 파이썬 패키지로 인식
      • 여기서는 Project App 디렉토리인 Costaurant이 패키지
      • 파이썬 3.3 버전 이상부터는 이 파일 없이도 파이썬 패키지로 인식
        • 하지만 하위 버전 호환을 위해 유지
    • settings.py : 프로젝트의 시간대 설정, 데이터베이스 설정, 여러 경로 설정 등
      • 장고 프로젝트의 전반적인 설정 담당
    • urls.py : URL 연결
      • URL을 보고 알맞은 페이지로 연결해 주는 역할
    • wsgi.py : WebServer Gateway Interface, WSGI
      • 웹서버와 Python 어플리케이션인 Django가 소통하는데 필요한 일종의 프로토콜

Django App

Project vs. App

  • 프로젝트: 웹서비스 전체
  • 앱: 기능을 나타내는 단위

앱 생성

python manage.py startapp foods

앱 생성 후 꼭 장고에게 앱을 새로 만들었다는 사실을 전달해야 함

  1. Project App의 settings.py로 이동
  2. INSTALLED_APPS = [ ~~~ ] ← 이 리스트에 추가한 앱 이름 추가 (single quotation mark)

앱 구조

  • init.py 파일이 있는 다이렉토리를 파이썬 패키지로 인식
  • admin.py : 앱을 장고 관리자와 연동하기 위해 필요한 설정 파일
  • apps.py : 앱에 대한 설정을 넣어두는 파일
  • models.py : django app에서 사용할 데이터 모델 정의
    • 데이터베이스 연동과 관련된 파일
  • views.py : django app의 메인 로직 처리와 관련된 파일
    • 서버에 요청이 들어왔을 때 어떻게 처리해야 하는지?
  • tests.py : 프로젝트의 테스트 코드를 작성하는 곳
  • migrations (다이렉토리) : 데이터베이스의 변경 사항 히스토리 누적

urls.py

urlpatterns (리스트) : url을 어떻게 처리할지 써놓는 곳

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

urlpatterns = [
		path('', include('foods.urls')), #메인페이지로 루팅
    path('admin/', admin.site.urls),
]
  • 우리 사이트 url 뒤에 admin/ 이 써있을 경우 admin.site.urls로 이동
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('foods/', include('foods.urls')),
]
  • url에 foods가 있다면 foods 파일의 urls.py를 확인해 보라는 뜻

foods app의 urls.py로 이동

from django.contrib import admin
from django.urls import path
from . import views # . 은 같은 파일을 의미

urlpatterns = [
    path('index/',views.index) 
]
  • foods app안의 views 파일을 봐라
  • views.index : views 파일의 index 함수

foods app의 views.py에 index 함수 정의

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse("<h2>Hello, Django!</h2>")

**URL을 적을때 앞에 슬래시가 있으면 도메인으로부터의 경로를 의미

<a href="/banana/">이동하기</a>

**URL을 적을때 앞에 슬래시가 없으면 현재 URL 뒤에 이동하는 URL이 연결된 경로가 됩니다

<a href="banana/">이동하기</a>

유저에게 template을 곧장 보여주기 (template을 rendering하기)

def index(request):
	return render(request,'foods/index.html')

클라이언트와 서버

클라이언트는 서버에게 무언가를 요청 (Request), 서버가 클라이언트의 요청에 응답 (Response)

  • 클라이언트: 웹브라우저 또는 앱
  • 서버: 여느 컴퓨터

url을 통해 요청

URL의 구조 = Domain (도메인) + Path (경로)

  • 도메인은 서버를 찾는다
    • Domain Name System: 인터넷 상의 주소록을 통해 검색
  • 경로는 요청하는 내용을 담고 있음: 서버 안에서 원하는 것이 있는 위치
  • 뒤에 슬래시 ( / )가 붙으면 디렉토리, 안 붙으면 파일

URL Routing

URL의 경로 항목에 어떤 경로를 입력하던지 간에 장고가 가장 먼저 확인하는 파일은 urls.py임

settings.py에 명시되어 있음

ROOT_URLCONF = 'costaurant.urls'

render()

render(request, template_name, context=None, 
				content_type=None, status=None, using=None)

render 함수는 인자로 주어진 템플릿을 사전형(dict) 인자인 context와 결합해서 렌더링을 거친 다음 HttpResponse 객체로 반환하는 함수입니다.

  • 인자로 넘겨주는 템플릿과 context 데이터를 합쳐서 HttpResponse 객체로 돌려주는 함수

필수 인자 : request & template_name

  • request: 데이터를 요청한 요청 객체
    • 요청에 대한 정보에 접근해서 user, session 등 여러가지 기능 구현을 위함
  • template_name: 렌더링에 사용할 대상 템플릿

선택 인자

  • context: 템플릿에 추가할 값들이 들어있는 사전형 인자
    • 기본값: None
  • content_type: 결과로 만들어내는 문서의 유형
    • 기본값: text/html (HTML 웹페이지)
  • status: 상태 코드 (Status code) 값
    • 기본값: 200 (성공)
    • 상태 코드는 클라이언트의 요청이 성공적으로 처리되었는지에 대한 정보를 주는 코드
  • Using: 템플릿을 렌더하는 템플릿 엔진을 지정할 수 있는 인자

Django MVT 아키텍처

MVT: Model, View, Template

Model: 데이터 구조 생성, 데이터베이스와 소통

Template: 웹사이트의 화면 구성 담당

  • 기본적인 틀은 HTML, CSS
  • 세부적인 내용은 template language 사용

View: 웹사이트의 로직 담당, Model과 Template 사이를 연결 (요청을 처리하는 역할)

  • 간단한 요청은 템플릿을 렌더링해서 응답
  • 복잡한 요청은 Model을 통해서 필요한 데이터를 가져온 다음 가져온 데이터를 알맞게 처리해서 처리된 데이터를 Template에 보내 필요한 화면을 렌더링하여 만들어진 HTML 코드로 응답

Architecture Pattern

: 소프트웨어 내부에 존재하는 구조적 패턴

  • 오랜 시간 개발된 다양한 소프트웨어들이 결국 내부적으로 비슷한 구조를 갖게 됨

대표적인 10가지 아키텍처 패턴

  1. 계층화 패턴, Layered pattern
  2. 클라이언트-서버 패턴, Client-server pattern
  3. 마스터-슬레이브 패턴, Master-slave pattern
  4. 파이프-필터 패턴, Pipe-filter pattern
  5. 브로커 패턴, Broker pattern
  6. 피어 투 피어 패턴, Peer-to-peer pattern
  7. 이벤트-버스 패턴, Event-bus pattern
  8. MVC 패턴, Model-view-controller pattern
  9. 블랙보드 패턴, Blackboard pattern
  10. 인터프리터 패턴, Interpreter pattern

클라이언트-서버 패턴

  • 소프트웨어를 내부적으로 두개의 구조로 나눠 서버는 클라이언트의 요청을 기다리고 있다가 클라이언트로부터 요청이 들어오면 요청에 맞는 서비스 제공
  • (예) 인터넷 웹사이트, 온라인 게임 등

MVC 패턴

  • 하나의 소프트웨러를 역할에 따라 Model, View, Controller 세가지의 파트로 나눠서 개발하는 패턴
    • Model: 데이터를 저장 보관
    • View: 사용자에게 보여지는 부분을 담당
    • Controller: 사용자의 입력을 받아서 내부 로직 처리
  • 역할 분리 덕에 분업 가능, 프로그램을 빠르게 개발, 유지보수 용이
  • MVC vs. MVT
    • MVC의 View의 역할을 MVT의 Template이 처리
    • MVC의 Controller의 역할을 MVT의 View가 처리

정적 파일, Static files

정적 파일: HTML 파일을 제외하고 웹페이지를 렌더링하는 데 필요한 추가적인 파일 (예) CSS, JS, 이미지, 폰트 파일

정적 파일 디렉토리 구조

{app 이름}/static/{app 이름 repeat}/{css, img, fonts, 등}

템플릿 태그

: static에 있는 정적 파일을 현재 이 템플릿 파일에서 사용한다고 알려주는 것

🔽 아래 코드를 템플릿 파일의 최상단에 입력

{% load static %}

🔽 아래 코드를 link (stylesheet) 경로 입력

<link rel="stylesheet" href={% static 'foods/css/styles.css'%}

디렉토리 구조

static의 구조: costaurant/foods/static/foods/{css, fonds, images, etc.}

template의 구조: costaurant/foods/template/foods/index.html

샌드위치 구조가 필요한 이유

  • 템플릿
    • Django는 앱이 등록된 순서대로 찾아보면서 일치하는 템플릿을 가져옴
    • 그래서 전에 오는 앱에 같은 이름의 디렉토리/파일이 있으면 무조건 그게 불려짐
  • 정적 파일 (이미지)
    • 개발한 서비스를 배포한 환경에서는 모든 정적파일들을 하나의 디렉토리에 모아서 사용하게 되는데, 같은 이름의 파일이 있으면 충돌이 일어남
    • 각각 다른 앱 이름의 디렉토리 안에 정적 파일을 넣어주면 하나의 디렉토리에 정적파일을 모아넣어도 앱 이름의 디렉토리로 구분됨

Template 언어

템플릿 언어: 화면을 구성하는 템플릿을 작성할때 보다 편리하게 작성하도록 도와주는 것

  • HTML 코드를 구성할때 프로그래밍처럼 구성 가능

템플릿 언어

  • 템플릿 변수: 우리가 지정한 데이터로 변환
  • 템플릿 태그: 템플릿 작성에 로직 사용
  • 템플릿 필터: 템플릿 변수를 특정 형식으로 변환
  • 템플릿 주석: 템플릿 언어의 주석처리를 담당

템플릿 변수 {{변수명}}

{{ variable }}
  • 템플릿 변수는 템플릿이 렌더될 때 해당 변수가 의미하는 값으로 변환됨
  • 뷰(View)에서 가공한 데이터를 템플릿으로 넘겨주면 템플릿에서는 템플릿 변수를 사용해 넘겨받은 데이터에 접근 가능
  • {{변수명.속성}} 도 가능
user = {"name" : "우재", "coffee" : True}
  • 위와 같은 경우에 User.name으로 “우재"라는 안쪽 값에 접근 가능
  • . 연산자는 다음과 같은 순서로 변수의 안쪽 속성에 접근 시도
    1. 변수를 사전형으로 생각하고 . 연산자로 key값 조회
    2. 변수를 객체로 생각하고 내부 속성값 조회 또는 함수 호출
    3. 변수를 리스트로 생각하고 점 연산자로 Index 조희

템플릿 필터 {{변수명 | 필터}}

{{ variable|filter }}
{{ variable}filter:args }}
  • 템플릿 변수를 특정 형식으로 변환
{{ variable|default:"coffee" }} #변수가 비어있거나 False면 coffee 텍스트로 대체
{{ variable|capfirst }} #맨 첫글자로 대문자로 변환
{{ variable|random }} #반복 가능한 템플릿 변수에 대해 무작위로 하나를 추출해 변환
			#variable의 참조값이 ["a", "b", "c", "d"]인 리스트형이라면 템플릿 변수가 
			#리스트 내의 하나의 원소로 대체
{{ variable | upper }} , {{ variable | lower }} #대문 또는 소문자 (lower)로 변환
{{ variable|ljust:"length" }}, {{ variable|rjust:"length" }}
			#주어진 길이 내에서 공백을 넣어 왼쪽 정렬(ljust) 또는 오른쪽 정렬(rjust)을 한 문자열로 변환

템플릿 태그 {% 태그 %} {%end태그%}

{% tag %}
{% tag %} ~ {% endtag %}
  • 템플릿 작성에 로직을 적용
  • (예) for loop
    • {% for %} {% endfor %}
{% for food in foods %} 
    <li> {{ food.name }} </li>
{% endfor %}

#목록을 역순으로 반복
{% for food in foods reversed %} 
    <li> {{ food.name }} </li>
{% endfor %}

#반복 가능한 객체가 비어있거나 존재하지 않을 때 
{% for food in foods %} 
    <li> {{ food.name }} </li>
{% empty %}
    <li> There is no food. </li>
{% endfor %}
  • (예) if else statement
    • {% if %} {% else %} {% endif %}
{% if hungry %}
    <p> Let's eat! </p>
{% elif sleepy %}
        <p> You need some coffee. </p>
{% else %}
    <p> Go back to work. </p>
{% endif %}
  • (예) 상속: 여러 파일의 공통적인 부분을 모아서 부모 파일을 만들어두고, 자식 파일에서는 공통된 부분을 부모 파일에서 상속받고 다른 것들은 직접 구현
    • {% block %} {% endblock %}
    • 자식 템플릿의 최상단에 부모템플릿 명시 (가장 첫줄)
    • 블락 이름 명시 후 block & endblock 사이에 코드 작성
{% extends './base.html' %} #base.html을 부모 템플릿으로 지정
{% load static %} #자식 템플릿에서도 정적 파일에 접근할 것이니 꼭 있어야함
{% block date-block %}
{% endblock %}
  • (예) with:
    • 복잡한 변수가 있을 때 '별명'을 붙이기 위해 사용
    • with 구문 내에서는 value1을 value2 대신 사용 가능
{% with value1=value2 %} ~ {% endwith %}

템플릿 주석 {# 주석 #}

  • 템플릿 언어의 주석 처리

동적 페이지

Untitled

  • View —> Template —> 화면 과정을 해볼 것임

매일 날짜/시간 바꾸기

#views.py 
from datetime import datetime

def index(request):
    today = datetime.today().date
    context = {"date":today} #render 함수의 세번째 인자는 dict 형태여야 함
    return render(request, 'foods/index.html', context=context)

#index.html
#대체하고자하는 변수에
<div>{{date}}</div>

우아하는 URL

Django의 URL은 우리가 원하는 형태로 구성 가능, 직관적이고 알아보기 쉬운 구조라는 장점

동적 URL, Dynamic URL

#url.py
urlpatterns = [
		path('index/', views.index),
		path('menu/<str:food>/', views.food_detail) #동적 path variable 이용
]
  • str에 int 또는 slug 등 사용 가능
    • < int : variable > : 0 또는 양의 정수와 일치하는지 확인
    • < slug : variable > : 문자, 숫자, 언더바, 하이픈으로 구성된 문자열인지 확인
#views.py
def food_detail(request, food):
    context = {"name": food}
    return render(request, 'foods/detail.html', context=context)
def city_detail(request, city):
    path_template = 'cities/'
    if city == 'seoul':
        path_template += 'seoul.html'
    elif city == 'tokyo':
        path_template += 'tokyo.html'
    elif city == 'paris':
        path_template += 'paris.html'
    else:
        path_template += 'index.html'
    return render(request, path_template)

URL 처리 순서

  1. 처음 요청이 들어오면 장고는 맨 처음 사용할 URLConf 모듈을 찾음. 따로 변경하지 않았다면 프로젝트 앱 내 settings.py의 ROOT_URLCONF 설정 사용
  2. ROOT_URLconf로 정의된 URLConf 모듈을 보고 urlpatterns 리스트 안쪽의 django.urls.path() 함수를 순서대로 실행
  3. 요청과 일치하는 URL 패턴이 있다면 django.urls.path() 함수에 따라 view를 호출하거나, 일치하는 URL 패턴 다음의 URL을 하위 URLconf 모듈로 넘김
from django.urls import path
from django.urls import include
from . import views

urlpatterns = [
    path('music/', views.player),
    path('video/', include('videoApp.urls')),
    # URL이 '~/video/lecture/django' 라면
    # videoApp의 URLconf에는 'lecture/django'가 넘어갑니다.
]

PATH 함수

django.urls.path

path(route, view, kwargs=None, name=None)
  • route: URL 문자열을 인수로 받으며 경로 변수(Path converter)를 사용하여 URL의 일부를 view의 인수로 보낼 수 있음
    • path converters: 경로 변환기/경로 변수
      • str: 경로 구분 기호(/)를 제외한 모든 문자열과 매칭
      • int: 0 또는 양의 정수와 매칭
      • slug: 문자, 숫자, 하이픈, 밑줄로 구성된 문자열과 매칭
      • uuid: 범용 고유 식별자 (UUID)와 매칭
      • path: 경로 구분 기호(/)를 포함한 모든 문자열과 매칭
  • view
    • 함수형 view 또는 클래스 기반 view가 들어갈 수 있음
    • include를 사용해서 다른 URLconf 모듈로 연결 가능
  • kwargs: view에 추가 인자를 전달할 때 사용
  • name
    • path 함수가 가지는 URL 패턴에 이름을 붙여 주기 위해 사용
    • URL을 직접 템플릿에 적지 않게 해주고 URL을 직관적으로 참조할 수 있게 해줌

URL, View, Template

def food_detail(request, food):
    context = dict()
    if food == "chicken":
        context["name"] = "코딩에 빠진 닭"
        context["description"] = "주머니가 가벼운 당신의 마음까지 생각한 가격!"
        context["price"] = 10000
        context["img_path"] = "foods/images/chicken.jpg"
    return render(request, 'foods/detail.html', context=context)

에러 페이지 처리하기

상태 코드, Status code: 요청에 대한 처리 결과가 어떻게 되었는지 알려주는 코드

  • 3자리 숫자
  • 크게 5가지로 분류

5가지

  • 1XX, informational: 요청을 받아서 작업을 진행하고 있음
    • 100 (continue): 요청의 첫부분을 받아서 다음 요청을 기다리는중. 이미 요청을 완료했다면 해당 응답 무시
    • 101 (Switching protocol): 클라이언트가 서버에게 프로토콜 전환을 요청했고 서버에서 프로토콜을 변경함
  • 2XX, Success: 요청에 대한 처리 결과가 정상
    • 200: 정상일 때 일반적으로 받는 상태 코드
    • 201 (Created): 요청이 성공적으로 처리되어 새로운 리소스 생성
    • 202 (Accepted): 서버가 성공적으로 요청을 받았지만 아직 처리 전인 상태
    • 203 (Non-authoritative information): 서버가 성공적으로 요청을 처리했지만 요청에 포함된 정보가 다른 곳에서 수정된 정보
    • 204: 정상 처리 되었지만, 서버에서 보내줄 데이터 없음
    • 205 (reset content): 요청을 성공적으로 처리했고 콘텐츠를 제공하지 않으며 클라이언트가 문서 보기를 재설정할 것을 요구
  • 3XX, Redirection: 요청을 완료하기 위해 추가적인 동작 필요
    • 300 (multiple choice): 요청에 대해 서버가 여러 응답이 가능하며 하나를 선택해야 함
    • 301: 요청한 자원이 새로운 주소로 옮겨짐
    • 302 (found): 요청한 리소스가 일시적으로 이동했음. 향후 다시 해당 리소스를 요청할 때도 동일한 주소로 해야함
    • 304: 요청에 대한 변경 사항이 없음 → 마지막으로 받았단 자원 사용
  • 4XX, Client error: 클라이언트의 요청에 문제가 있음
    • 400 (bad request): 클라이언트으 ㅣ요청을 서버가 이해 X
    • 401 (Unauthorized): 클라이언트가 해당 요청에 대한 응답을 받기 위해서는 추가적인 인증이 필요
    • 402 (payment required): 이 요청은 결제가 필요함. 처음 이 응답 코드가 만들어질 당시에는 결제 시스템에 사용할 목적이었으나 현재는 사용 X
    • 404: 요청한 자원이 없음
    • 403: 요청한 자원에 대한 접근 권한이 없음, 요청은 이해했으나 금지됨
  • 5XX, Server error: 서버가 요청을 처리하는 과정에서 문제 발생
    • 500: 서버 내부 오류 의미
    • 501 (not implemented): 클라이언트가 요청한 방법을 서버에서 수행할 수 있는 기능이 없음
    • 502 (bad gateway): 서버가 요청을 처리하는데 필요한 작업 중 게이트웨이로부터 잘못된 응답을 받았음
    • 503 (service unavailable): 서버가 해당 요청을 처리할 준비가 되지 않았으며 일반적으로는 유지관리를 위해 작동이 중단되거나 과부하가 걸렸을 때를 나타냄 (대개 일시적)

Example

#views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.http import Http404

def food_detail(request, food):
    context = dict()
    if food == "chicken":
        context["name"] = "코딩에 빠진 닭"
        context["description"] = "주머니가 가벼운 당신의 마음까지 생각한 가격!"
        context["price"] = 10000
        context["img_path"] = "foods/images/chicken.jpg"
    else:
        raise Http404("이런 음식은 없다구요!")
    return render(request, 'foods/detail.html', context=context)

Model 이해하기

Model: 데이터의 구조를 잡아주고 정의된 구조를 기반으로 데이터베이스와 소통

데이터의 구조: 우리가 저장할 정보들의 형태

  • 데이터 모델링: 각각의 데이터 구조와 형식을 저장하는 것

데이터베이스: 실제로 데이터를 저장하는 곳 (예) MySQL, PostgreSQL, etc.

  • 추가 (Create), 조회 (Read), 수정 (Update), 삭제 (Delete)

ORM, Object-Relational Maper

  • 파이썬을 이용해 데이터베이스와 소통하는 방법
  • 모델이 제공하는 기능
  • 서비스의 요구사항에 맞게 모델을 정리한 다음 파이썬 코드를 쓰면 장고가 인식하여 이에 맞는 SQL 코드를 자동으로 만들어 실행 후 데이터베이스에 저장

Model 작성

  • 모든 모델은 클래스로 구성
#models.py
class Menu(models.Model): #장고의 models.Model 상속
		name = models.CharField(max_length=50) #max_length는 필수인자
    description = models.CharField(max_length=100)
    price = models.IntegerField()
    img_path = models.CharField(max_length=255)

    def __str__(self): #하나의 객체를 문자열로 표현, print(menu)를 썼을 때 결과로 나오는 문자열 결정
        return self.name
  • 장고에게 사용하는 모델이 바뀌었다고 얘기해야 함
./manage.py makemigrations <myapp>
python manage.py migrate

Django의 Model Field

Django Model은 대부분의 데이터를 저장할 수 있는 필드를 지원하는데 모든 필드에 사용할 수 있는 공통 옵션이 있고, 각각의 필드마다 갖고 있는 고유 옵션이 있음

Field 종류

  • field, 필드: 데이터 테이블에서의 열(column), 즉 데이터의 속성을 의미
  • CharField: 제한된 길이의 문자열을 위한 필드
    • max_length: 필수 인수이며 입력할 최대 길이 설정
    • (ex) models.CharField(max_length=None)
  • IntegerField: 정수값을 위한 필드. -2147483648부터 2147483647 범위 지원
    • (ex) models.IntegerField()
  • BooleanField: boolean값을 위한 필드
    • (ex) models.BooleanField()
  • DateField: 파이썬의 datetime.date 객체 형태로 표시되는 날짜 필드
    • (ex) models.DateField(auto_now=False, auto_now_add=False)
    • auto_now: true면 해당 객체가 변경(save)될 때마다 자동으로 필드 값을 지금으로 수정 (예) 마지막 수정 시간
    • auto_now_add: 모델이 처음 생성될 때 한 번 자동으로 필드 값을 지금으로 설정 (예) 생성된 시간
  • DateTimeField: 파이썬의 datetime.datetime 객체 형태로 표시되는 날짜 필드
    • (ex) models.DateTimeField(auto_now=False, auto_now_add=False)
  • EmailField: 이용 가능한 이메일 주소인지 EmailValidator를 통해 확인
    • CharField의 하위 클래스
    • (ex) models.EmailField(max_length=254)
  • FileField: 파일 업로드를 위한 필드
    • (ex) models.FileField(upload_to=None, max_length = 100)
    • upload_to: 업로드될 경로를 지정하는 필드로 Storage.save()로 값이 전달되어 저장
  • ImageField: FileFiled를 상속하여 구현되는 파일 업로드를 위한 필드
    • 기본적으로 최대 길이가 100인 문자열 형식으로 생성
    • FileField에서 업로드된 파일이 정상적인 이미지 파일인지 확인하는 과정이 추가된 필드
    • 이미지 처리를 위한 Pillow 라이브러리가 필수적으로 필요
    • (ex) models.ImageField(upload_to=None, height_field = None, width_field=None, max_length=100)
    • height_field & width_field: 객체가 저장될 때 이미지의 높이와 너비값이 자동으로 채워짐

Option 종류

아래 옵션은 모든 필드 타입에 사용 가능, 선택적으로 적용 가능

  • null
    • (ex) Field.null
    • 기본 값은 False
    • Null 값 허용 여부 선택
    • 만약 이 null 옵션을 적용할 필드가 문자열 기반 필드(Char/Text)일 경우에는 주의해서 사용해야 함
      • ‘’(빈 문자열)과 Null 모두 해당 필드의 데이터가 없다는 것을 의미
      • 일반적으로 데이터가 없다는 것을 의미하는 값은 하나여야 하므로 Django는 문자열 기반 필드가 데이터가 없음을 표기할 때는 ‘’(빈 문자열) 권장
  • blank
    • (ex) Field.blank
    • 기본 값은 False. True로 설정한 경우 필드 값을 빈 값으로 설정
    • null vs. blank
      • null: 온전히 데이터베이스와 관련된 사항
      • blank: 데이터의 유효성 검사와 관련된 옵션
        • blank가 True라면 해당 필드에 데이터를 입력하지 않아도 유효성 검사 통과
  • default
    • (ex) Field.default
    • 필드의 기본값을 설정하는 옵션
    • 값 또는 함수가 들어감
  • db_column
    • (ex) Field.db_column
    • 해당 필드에 사용할 데이터베이스 속성 명 지정
    • 따로 지정하지 않을 경우 일반적으로 필드 이름 사용

Migration

모델의 변경사항은 반영해줘야 함

Migration: 장고의 데이터베이스 변경 사항에 대한 버전 컨트롤 시스템

  • 변경 사항을 저장해둔 목록
  • 개발자가 모델을 생성/변경했을 때 마이그레이션을 하나씩 만드는 것
  • migrate: 만든 마이그레이션을 실제 데이터베이스에 적용

Migration 파일

  • 장고가 자동으로 생성
    • id: 각각의 데이터를 구분하기 위한 고유값
      • 중복 X
      • 장고에서 자동으로 생성해주는 코드

모델이 어떻게 변환되었는지 확인하기

python manage.py showmigrations
python manage.py sqlmigrate {app name} {migration #}

데이터 추가하기, create

장고의 유용한 기능을 그대로 사용할 수 있는 Shell 환경 열기

  • shell: 사용자의 명령을 받아서 해석한 다음 프로그램 실행
python manage.py shell

모든 데이터 조회하기

{model}.objects.all()

데이터베이스에 데이터 저장하기

{model}.objects.create({필드명}={})
Author.objects.create(name="Joe")

세부 데이터까지 조회하기

{model}.objects.all().values

Django Shell vs. Python Shell

Django Shell: 파이썬 shell 환경에 Django 프로젝트를 shell에서 바로 접근할 수 있도록 하는 환경 설정이 더해진 것

  • 기존의 파이썬 shell만으로는 django에서 제공하는 기능 사용 X
    • Django가 사용할 환경설정을 찾지 못하기 때문

데이터 갖고 놀기

데이터베이스 대표적 기능

  • Create, 데이터 생성
  • Read, 데이터 조회
  • Update, 데이터 수정
  • Delete, 데이터 삭제

조회하고 싶은 필드만 보기

{model}.objects.all().values({field name})
#field name put in single quotation marks

필드로 정렬하기

{model}.objects.order_by({field name}) #field name in single quotation marks
#field name 앞에 '-'을 붙이면 reverse order

특정 조건에 맞는 필드 가져오기: 필드명__조건키워드=”조건”

  • get: 하나의 데이터 조회 (조회 결과가 두개 이상이면 에러)
    • id 같은 필드를 조회할 때 사용
{model}.objects.get(id={int})
  • filter: 여러 데이터 조회
{model}.objects.filter({field}__contains={str})
{model}.objects.filter({field}__range=({int},{int})
#날짜, 숫자, 문자 등 모든 데이터의 범위 사용 가능

데이터 수정하기

data = Menu.objects.get(id=1)
data.name = "코빠닭"
data.save() #데이터베이스에 반영

데이터 삭제하기

data = Menu.objects.get(id=3)
data.delete()

데이터 개수 세기

rows = {model}.objects.count()

특정 조건을 제외한 데이터 조회하기

data = {model}.objects.exclude(field=value)
# 특정 field가 value인 데이터를 제외한 모든 데이터를 조회합니다.

체인으로 연결해서 조회하기

data = {model}.objects.filter(price=10000).order_by('name')
# 가격(price)이 10,000원인 데이터를 이름(name)으로 정렬해서 조회
data = {model}.objects.filter(price=10000)
data = data.order_by('name')
# 이렇게 적어도 위와 똑같은 명령을 수행

조건 키워드

{field_name}__{keyword}={condition}

  • exact, iexact
    • __exact: 대소문자 구분
    • __iexact: 대소문자 구분 X
data = {model}.objects.filter(name__iexact='chicken')
# 음식의 이름(name)이 'chicken'인 데이터를 모두 조회
# 대소문자 구분 ㅌ
  • contains, icontains: 지정한 문자열을 포함하는지
data = {model}.objects.filter(name__contains='chicken')
#음식의 이름에 'chicken'이 포함된 모든 데이터 조회
#대소문자 구분
  • lt, gt, lte, gte
    • 미만 (less-than), 초과(greater-than), 이하(less-than-or-equal), 이상(greater-than-or-equal)인 데이터 조회
data = {model}.objects.filter(age__gt=25)
  • __in: 주어진 리스트 안에 존재하는 자료 조회
data = {model}.objects.filter(age__in=[21,25,27])

QuerySet

Queryset[]: 장고의 ORM을 이용해 데이터베이스와 소통할 때 발생하는 자료형

  • 리스트와 매우 비슷함

파이썬 코드가 어떤 SQL로 변환되었는지 확인해보기

print(data.query)

관리자 도구 사용하기, Admin

  1. 관리자 계정 생성
#shell에 작성
python manage.py createsuperuser
  1. 관리자가 작업할 수 있도록 모델을 추가해줘야함
#admin.py

from django.contrib import admin
from foods.models import Menu

# Register your models here.
admin.site.register(Menu)

Model 적용하기

하드코딩, HardCoding: 소스 코드 안에 데이터가 직접 입력되어 있는 코딩 형태

  • 지양해야 하는 형태
  • 데이터 유실 위험, 유지 보수 어려움
#views.py
from django.shortcuts import render
from django.http import HttpResponse
from datetime import datetime
from django.http import Http404
from foods.models import Menu

# Create your views here.
def index(request):
    context = dict()
    today = datetime.today().date()
    menus = Menu.objects.all()
    context["date"] = today
    context["menus"] = menus
    return render(request, 'foods/index.html', context=context)

#index.html
{% for menu in menus %}
  <div class="food">
    <img src={% get_static_prefix %} {{menu.img_path}} width="300px" height="200px"/>
    <div class="info">
      <h3>{{menu.name}}</h3>
      <P>{{menu.description}}</p>
      <a href="#">메뉴 보기</a>
    </div>
  </div>
{% endfor %}

프로젝트 완성하기

#urls.py
from django.contrib import admin
from django.urls import path
from . import views # . 은 같은 파일을 의미

urlpatterns = [
    path('menu/',views.index),
    path('menu/<int:pk>/',views.food_detail),
]
#views.py
from django.shortcuts import render
from django.http import HttpResponse
from datetime import datetime
from django.http import Http404
from foods.models import Menu

# Create your views here.
def index(request):
    context = dict()
    today = datetime.today().date()
    menus = Menu.objects.all()
    context["date"] = today
    context["menus"] = menus
    return render(request, 'foods/index.html', context=context)

def food_detail(request, pk):
    context = dict()
    menu = Menu.objects.get(id=pk)
    context["menu"] = menu
    return render(request, 'foods/detail.html', context=context)

Django를 배포할 수 있는 2가지 방법

클라우드 서비스, Cloud service: 업체가 서버를 제공하고 일반 사람들은 해당 서버를 네트워크를 통해 사용

서버를 위한 클라우드 서비스 2가지, 차이는 개발자가 서비스의 어디까지 설정해서 사용할 수 있는가

  • IaaS: Infrastructure as a Service
    • 서버 장비만 빌려서 사용하는 방식
    • 업체에서 장비에 개발자가 선택한 운영체제만 설치해서 네트워크로 제공해주ㅁ
    • 개발자가 필요한 프로그램을 직접 설치 및 설정
    • 복잡하지만 내가 필요한 최적의 환경 구성 가능
  • PaaS: Platform as a Service
    • 서버 장비, 운영체제, 실행환경 제공
    • 전체적인 실행환경이 갖춰져있음
    • (ex) AWS의 Elastic Beanstalk, Google App Engine, etc.
    • 우리가 사용해볼 pythonanywhere (python app에 특화된 서비스)

배포 준비 단계

  1. 디버그 모드 끄기
    • 디버그 모드: 에러 발생 시 자세한 에러 페이지 표시
    • 디버그 모드를 끄지 않으면 구성 정보 등 민감정보 노출 위험도가 올라감
#project app의 settings.py
DEBUG = False
  1. 호스트 설정하기: 우리가 허용할 호스트 설정
    • 배포할 때 사용할 주소를 이 곳에 적어 해당 서버가 우리 웹사이트를 호스트할 수 있게 함
    • 호스트가 없으면 내 컴퓨터 서버에서만 배포 가능
#project app의 settings.py
ALLOWED_HOSTS = ['.pythonanywhere.com']
  1. 정적 파일 한곳으로 모으기 (파일 이름이 중복되지 않게)
#project app의 settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
  • STATIC_URL
    • 웹에서 정적파일에 대한 URL을 할당할 때 사용할 최상위 URL
    • 실제로 존재하는 디렉토리가 아닌 URL을 만들기 위한 부분
    • (ex) STATIC_URL=’/static_files/’ → ~/static_files/정적 파일
  • STATIC_ROOT
    • 실제로 정적파일이 모아지는 경로
    • Django 프로젝트에서 사용하는 모든 정적 파일이 이 경로에 복사됨
#shell
python manage.py collectstatic

PythonAnywhere로 배포하기

  1. 프로젝트 디렉토리 전체 압축
  2. zip 파일을 pythonanywhere의 file에 업로드
  3. pythonanywhere의 bash console 열기
  4. bash console에서 압축 해제
    • unzip (파일명)
    • unzip costaurant.zip
  5. 이 서버에 python 가상환경 만들기
    • virtualenv —python=python3.7 (가상환경이름)
    • virtualenv —python=python3.7 django-envs
  6. 가상환경으로 이동
    • cd django-envs
    • source bin/activate
  7. django 설치
    • pip install django==2.2
  8. pythonanywhere의 web으로 이동
  9. web app 생성 → next → manual configuration → Python 3.7 → next
  10. 하단의 Code 부분 수정
    • source code에 /home/{나의 id}/{프로젝트명}
    • WSGI 링크를 클릭해서
      • line 19~47 주석처리 (cmd+/)
      • line 76~89 주석해제
      • line 81 & 85 의 mysite → costaurant
      • save 누르기
  11. Code 아래의 Virtualenv 설정
    • /home/{나의 id}/{아까 생성한 가상환경 이름}
  12. 하단의 Static files 설정
    • url에 /static
    • directory에 /home/{나의 id}/{프로젝트 디렉토리}/{static directory}
  13. 최상단의 reload 클릭

참고: 코드잇 장고 강의

profile
우당탕탕

0개의 댓글