- 장고는 웹 프로그램을 쉽고 빠르게 만들어 주는 웹 프레임워크다
- 장고는 웹 프로그램을 쉽고 빠르게 만들 수 있도록 도와주는 웹 프레임워크이다.
- 웹 프레임워크는 웹 프로그램을 만들기 위한 스타터 키트라고 생각하면 된다. 그리고 파이썬으로 만들어진 웹 프레임워크 중 하나가 바로 장고이다.
- 브랜치 이해하기
브랜치란 독립적으로 어떤 작업을 진행하기 위한 개념입니다. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있습니다.
# pybo 의 github 주소
https://github.com/pahkey/djangobook
# 워크스페이스에 pybo_src라는 폴더 생성 후 진입
mkdir ~/workspace/pybo_src && cd ~/workspace/pybo_src
# 깃 허브에 파일 복사
git clone https://github.com/pahkey/djangobook.git
cd djangobook
# 브랜치 확인하기
git branch -a
# 장고 프로젝트 생성 (현재 디렉토리(pybo_0427)에 config라는 프로젝트 만들기)
django-admin startproject config .
# 장고 앱 생성
django-admin startapp pybo
# config/urls.py에서 url 매핑 경로 추가하기
from django.contrib import admin
from django.urls import path
from pybo import views #추가
urlpatterns = [
path('admin/', admin.site.urls),
path('pybo/', views.index), #추가
]
URL 매핑을 위해 config/urls.py에서 #추가 주석처리 된 코드를 추가하였다.
pybo/라는 URL이 요청되면 views.index를 호출하도록 했다.
그리고 pybo/views.py에 들어가서 index함수를 만들었다.
from django.http import HttpResponse
def index(request):
return HttpResponse("안녕하세요 pybo에 오신것을 환영합니다.")
http://localhost:8000/pybo 로 브라우저에서 검색하면 아래와 같은 화면이 나타난다.
데이터베이스가 필요한 앱만 migrate가 필요하다.
- 마이그레이션이란 데이터베이스 스키마의 변경사항을 기록하는 것으로, Django에서는 모델을 수정할 때마다 이를 적용하기 위해 마이그레이션 파일을 생성합니다.
- 마이그레이션 파일은 데이터베이스 스키마에 대한 변경 내용을 기록하며, 이를 데이터베이스에 적용함으로써 변경 사항을 반영합니다.
질문을 만들기 위해 admin을 사용해야 하므로 migrate 한다.
# config/settings.py 데이터베이스 엔진은 django.db.backends.sqlite3
(... 생략 ...)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
(... 생략 ...)
python manage.py migrate # 질문 데이터베이스를 이용하기 위해 마이그레이트 해줌
# 위치 - pybo/models.py
from django.db import models
class Question(models.Model):
subject = models.CharField(max_length=200)
content = models.TextField()
create_date = models.DateTimeField()
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
content = models.TextField()
create_date = models.DateTimeField()
- Question 모델은 제목(subject), 내용(content) 그리고 작성일시(create_date)를 속성으로 갖도록 작성했다. 제목은 최대 200자까지 가능하도록 max_length=200을 설정하였다. 제목처럼 글자수의 길이가 제한된 텍스트는 CharField를 사용한다. 내용(content)처럼 글자수를 제한할 수 없는 텍스트는 위처럼 TextField를 사용한다. 작성일시처럼 날짜와 시간에 관계된 속성은 DateTimeField를 사용한다.
- Answer 모델은 질문에 대한 답변에 해당되므로 Question 모델을 속성으로 가져가야 한다. 기존 모델을 속성으로 연결하려면 ForeignKey를 사용해야 한다. ForeignKey는 다른 모델과 연결하기 위해 사용한다.
- on_delete=models.CASCADE의 의미는 이 답변과 연결된 질문(Question)이 삭제될 경우 답변(Answer)도 함께 삭제된다는 의미이다.
python manage.py createsuperuser
http://localhost:8000/admin/ 페이지 접속
Question 생성하기
관리자 화면에서 Question 모델을 관리할 수 있다. "테스트 질문"이라고 입력 후 질문 상세에는 "테스트 질문입니다"를 만들어 저장했다.
# 위치 - pybo/views.py
from django.shortcuts import render
from .models import Question
def index(request):
question_list = Question.objects.order_by('-create_date')
context = {'question_list': question_list}
return render(request, 'pybo/question_list.html', context)
질문을 역순으로 조회하여 정렬하고, 질문 목록을 조회한 것을 render를 이용하여 템플릿에 적용하여 html로 반환하여 페이지에 출력되게 만들었다.
config/settings.py
(... 생략 ...)
TEMPLATES = [
'DIRS': [BASE_DIR / 'templates'], # dir 위치 추가
(... 생략 ...)
templates 디렉토리가 없으니 생성해준다.
pybo_0427 폴더에서
mkdir templates
templates 폴더에서 render 함수에서 사용한 pybo/question_list.html 파일을 만들어야 한다.
{% if question_list %}
<ul>
{% for question in question_list %}
<li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>질문이 없습니다.</p>
{% endif %}
아래 URL을 브라우저에 입력하면 아래와 같은 화면이 출력된다.
# 위치 - /pybo/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('<int:question_id>/', views.detail), # 추가
]
이제 http://localhost:8000/pybo/1/ 페이지가 요청되면 여기에 등록한 매핑 룰에 의해 http://localhost:8000/pybo/<int:question_id>/ 가 적용되어 question_id 에 1가 저장되고 views.detail 함수도 실행시킨다.
# 위치 - /pybo/views.py
(... 생략 ...)
def detail(request, question_id):
question = Question.objects.get(id=question_id)
context = {'question': question}
return render(request, 'pybo/question_detail.html', context)
# 위치 - /templates
<h1>{{ question.subject }}</h1>
<div>
{{ question.content }}
</div>
모든 적용을 마치고 실행하여 보면 아래와 같은 경로를 입력했을 때, 아래 그림과 같이 웹페이지가 출력된다.
Template 태그 : {% 문법 %}
Template 변수 : {{ 변수 }}
Template 필터 : {{ 변수|옵션 }}