9 Sat
TIL
[배프의 오지랖 파이썬 웹프로그래밍]
3 튜토리얼 따라하기 - 설문조사
3. 1 프로젝트 만들기
프로젝트 명 : polls
장고 설치
pip install django
프로젝트 생성
django-admin startproject config .
3. 2 웹서버
웹 서버 시작하기
python manage.py runserver
포트 변경
python manage.py 8080
python manage.py 0.0.0.0:8080
python manage.py 0:8000
(근데 나는 잘 안된다)
3.3 설문조사 앱 만들기
앱 생성
python manage.py startapp polls

3.4 첫번째 뷰 만들기
polls/views.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
# Create your views here.
뷰를 만들면 이 뷰를 호출하기 위한 URL이 있어야 한다. URL 연결을 위해 polls 폴더에 urls.py 생성
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
]
path 함수는 path(route, view, kwargs, name) 형태로 호출한다.
route : 주소를 의미
view : 1의 주소로 접근했을 때 호츌할 뷰
kwargs : 뷰에 전달할 값
name : route의 이름을 의미. 이 이름을 가지고 원하는 곳에서 주소를 호출할 수 있다.
이 때, polls/urls.py
는 앱의 라우팅만 담당하므로 프로젝트의 메인 urls.py
에서 연결을 해줘야 정상 작동한다.
config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('polls/', include('polls.urls'))
path('admin/', admin.site.urls),
]
include는 다른 urls.py 파일을 참조할 수 있도록 해준다.

3.5 데이터베이스 만들기
config/settings.py
의 76번째 줄에는 데이터 베이스 설정이 있다.
ENGINE : 어떤 종류의 데이터베이스를 사용할지 설정
기본적으로 다음과 같은 4가지를 사용할 수 있다
django.db.backends.sqlite3
django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.oracle
데이터베이스 초기화
python manage.py migrate
3.6 모델 만들기
모델은 데이터베이스의 구조도이다. 데이터베이스에 어떤 테이블을 만들고 어떤 컬럼을 갖게 할 지 결정하며 컬럼의 제약 조건까지도 모델에서 결정한다.
polls/models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=20)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
장고의 모델은 models.Model을 상속받아 만드는데, 이 부모 클래스가 실제로 데이터베이스와 ORM을 이용해 동작하는 기능들을 가지고 있다.
각 클래스 변수들은 필드 값을 가지며 이 필드는 자료형과 같다.
ForeignKey는 다른 모델과의 관계를 만들기 위해서 사용한다. Choice 모델이 ForeignKey로 Question 모델을 갖는다는 것은 Choice 모델이 Question에 소속된다는 것을 의미한다.
모델을 완성하면 데이터베이스에 적용해야 한다. 이 때 사용하는 명령어는
migrate
이다. 또한, 이 명령을 사용하려면 polls 앱이 현재 프로젝트에 설치되어 있다고config/settings.py
에 명시해줘야 한다.
config/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig'
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
polls.apps.PollsConfig
는 polls 앱 폴더에 apps.py 파일에 있는 PollsConfig 클래스를 의미한다. 짧게 쓰려면 polls 라고만 입력해도 된다.
데이터 베이스 적용
python manage.py makemigrations polls
명령을 실행하면 앱의 변경사항을 파악해서 데이터베이스에 적용할 내용을 만들어 낸다. 이 내용이
polls/migrations/0001_initial.py
파일에 기록되어 있다.
SQL 구문 확인
python manage.py sqlmigrate polls 0001
이를 통해 SQL을 실행하거나 문제가 있는 쿼리를 판단할 수 있다.
그러나 장고를 사용하면 쿼리문을 몰라도 ORM을 통해 데이터베이스에 접근할 수 있다.
데이터베이스 반영
python manage.py migrate polls 0001
이 명령을 통해 데이터베이스에 변경사항을 반영하여 테이블을 생성하고 초기화 할 수 있다.
3.7 모델에 함수 추가하기
Question 모델과 Choice 모델에 __str__
메서드를 추가한다.
polls/models.py
from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
question_text = models.CharField(max_length=20)
pub_date = models.DateTimeField('date published')
def __str(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str(self):
return self.choice_text
모델을 작성한 후에 단순 메서드 변경은 migrate를 할 필요가 없다.
3.8 관리자 페이지 확인
관리자 페이지에 접근하기 위해서는 관리자 계정이 필요하다.
python manage.py createsuperuser


관리자 페이지에서 Question 모델을 관리하려면 이 모델을 등록해야 한다. admin.py
파일에서 다음 코드를 입력한다.
from django.contrib import admin
from .models import Question
admin.site.register(Question)

3.9 여러 가지 뷰 추가
튜표 앱의 메인 페이지 이후 여러 가지 뷰를 추가한다
투표 목록
투표 상세
투표 기능
투표 결과
views.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
3개의 뷰를 만들고 URL을 연결했다. index뷰와 다른 점은 각 URL에 있는 화살괄호는 변수를 의미하며 이 부분에 해당하는 값을 뷰에 인자로 전달한다.
polls/views.py
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)

기능이 있는 뷰를 만들었지만 MTV 패턴에 따르지 않은 형태이다. 템플릿을 만들어 파이썬 코드와 HTML 코드를 분리한다.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
</body>
</html>
polls/views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
loader를 이용해 index.html을 불러오고 미리 만들어 놓은 context 변수를 이용해 전달한다. 하지만 이런 절차가 약간 불편하기 때문에 장고에서는 render라는 단축함수를 제공한다.
polls/views.py
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {
'latest_question_list': latest_question_list,
}
return render(request, 'polls/index.html', context)
render 메서드는 request와 템플릿 이름, 사전형 객체를 인자로 받는다. 사전형 객체는 템플릿에서 사용할 변수를 의미.


템플릿이 반영된 메인 화면
Last updated
Was this helpful?