Make directory (ex) codeit-django
mkdir codeit-django
특정 디렉토리에 로컬 가상 환경 적용
pyenv local {가상환경 이름}
설치된 장고 버전 확인
django-admin --version
장고 프로젝트 생성
django-admin startproject {프로젝트 이름}
장고 개발 서버 실행
python manage.py runserver
list files
ls
Project vs. App
앱 생성
python manage.py startapp foods
앱 생성 후 꼭 장고에게 앱을 새로 만들었다는 사실을 전달해야 함
앱 구조
urlpatterns (리스트) : url을 어떻게 처리할지 써놓는 곳
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('', include('foods.urls')), #메인페이지로 루팅
path('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')),
]
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.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 (경로)
URL의 경로 항목에 어떤 경로를 입력하던지 간에 장고가 가장 먼저 확인하는 파일은 urls.py임
settings.py에 명시되어 있음
ROOT_URLCONF = 'costaurant.urls'
render(request, template_name, context=None,
content_type=None, status=None, using=None)
render 함수는 인자로 주어진 템플릿을 사전형(dict) 인자인 context와 결합해서 렌더링을 거친 다음 HttpResponse 객체로 반환하는 함수입니다.
필수 인자 : request & template_name
선택 인자
MVT: Model, View, Template
Model: 데이터 구조 생성, 데이터베이스와 소통
Template: 웹사이트의 화면 구성 담당
View: 웹사이트의 로직 담당, Model과 Template 사이를 연결 (요청을 처리하는 역할)
: 소프트웨어 내부에 존재하는 구조적 패턴
대표적인 10가지 아키텍처 패턴
클라이언트-서버 패턴
MVC 패턴
정적 파일: 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
샌드위치 구조가 필요한 이유
템플릿 언어: 화면을 구성하는 템플릿을 작성할때 보다 편리하게 작성하도록 도와주는 것
템플릿 언어
템플릿 변수 {{변수명}}
{{ variable }}
user = {"name" : "우재", "coffee" : True}
템플릿 필터 {{변수명 | 필터}}
{{ 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 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 hungry %}
<p> Let's eat! </p>
{% elif sleepy %}
<p> You need some coffee. </p>
{% else %}
<p> Go back to work. </p>
{% endif %}
{% extends './base.html' %} #base.html을 부모 템플릿으로 지정
{% load static %} #자식 템플릿에서도 정적 파일에 접근할 것이니 꼭 있어야함
{% block date-block %}
{% endblock %}
{% with value1=value2 %} ~ {% endwith %}
템플릿 주석 {# 주석 #}
매일 날짜/시간 바꾸기
#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>
Django의 URL은 우리가 원하는 형태로 구성 가능, 직관적이고 알아보기 쉬운 구조라는 장점
동적 URL, Dynamic URL
#url.py
urlpatterns = [
path('index/', views.index),
path('menu/<str:food>/', views.food_detail) #동적 path 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 처리 순서
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)
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: 요청에 대한 처리 결과가 어떻게 되었는지 알려주는 코드
5가지
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: 데이터의 구조를 잡아주고 정의된 구조를 기반으로 데이터베이스와 소통
데이터의 구조: 우리가 저장할 정보들의 형태
데이터베이스: 실제로 데이터를 저장하는 곳 (예) MySQL, PostgreSQL, etc.
ORM, Object-Relational Maper
#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 종류
Option 종류
아래 옵션은 모든 필드 타입에 사용 가능, 선택적으로 적용 가능
모델의 변경사항은 반영해줘야 함
Migration: 장고의 데이터베이스 변경 사항에 대한 버전 컨트롤 시스템
Migration 파일
모델이 어떻게 변환되었는지 확인하기
python manage.py showmigrations
python manage.py sqlmigrate {app name} {migration #}
장고의 유용한 기능을 그대로 사용할 수 있는 Shell 환경 열기
python manage.py shell
모든 데이터 조회하기
{model}.objects.all()
데이터베이스에 데이터 저장하기
{model}.objects.create({필드명}={값})
Author.objects.create(name="Joe")
세부 데이터까지 조회하기
{model}.objects.all().values
Django Shell: 파이썬 shell 환경에 Django 프로젝트를 shell에서 바로 접근할 수 있도록 하는 환경 설정이 더해진 것
데이터베이스 대표적 기능
조회하고 싶은 필드만 보기
{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
특정 조건에 맞는 필드 가져오기: 필드명__조건키워드=”조건”
{model}.objects.get(id={int})
{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}
data = {model}.objects.filter(name__iexact='chicken')
# 음식의 이름(name)이 'chicken'인 데이터를 모두 조회
# 대소문자 구분 ㅌ
data = {model}.objects.filter(name__contains='chicken')
#음식의 이름에 'chicken'이 포함된 모든 데이터 조회
#대소문자 구분
data = {model}.objects.filter(age__gt=25)
data = {model}.objects.filter(age__in=[21,25,27])
Queryset[]: 장고의 ORM을 이용해 데이터베이스와 소통할 때 발생하는 자료형
파이썬 코드가 어떤 SQL로 변환되었는지 확인해보기
print(data.query)
#shell에 작성
python manage.py createsuperuser
#admin.py
from django.contrib import admin
from foods.models import Menu
# Register your models here.
admin.site.register(Menu)
하드코딩, 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)
클라우드 서비스, Cloud service: 업체가 서버를 제공하고 일반 사람들은 해당 서버를 네트워크를 통해 사용
서버를 위한 클라우드 서비스 2가지, 차이는 개발자가 서비스의 어디까지 설정해서 사용할 수 있는가
#project app의 settings.py
DEBUG = False
#project app의 settings.py
ALLOWED_HOSTS = ['.pythonanywhere.com']
#project app의 settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
#shell
python manage.py collectstatic
참고: 코드잇 장고 강의