url - view - template가 어떻게 연결되는지 복습해보자
먼저 view는 장고 웹의 파일 업로드, 다운로드 등의 로직은 담당한다. 다음과 같은 로직을 추가해보자
polls/view.py
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 looking 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
view.py에 다음과 같은 코드를 추가하자
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path("", views.index, name="index"),
# ex: /polls/5/
path("<int:question_id>/", views.detail, name="detail"),
# ex: /polls/5/results/
path("<int:question_id>/results/", views.results, name="results"),
# ex: /polls/5/vote/
path("<int:question_id>/vote/", views.vote, name="vote"),
]
클라이언트가 polls
를 호출하게 되면 view.index를 호출하게 된다.view의 index를 보면 Hello, world
를 출력하도록 해놓았다. 클라이언트가 polls/5
를 호출하게 되면 question_id
에 5를 담아 view.detail을 호출하게 되고, view.py의 detail은 You're looking at question %s
를 출력한다.
view에서는 단순하게 문자열을 출력하는 것 이외에 데이터베이스의 레코드를 읽을 수 있다.
polls/view.py
from django.http import HttpResponse
from .models import Question
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)
index함수를 위와 같이 수정하였다.
서버에 접속하여 http://127.0.0.1:8000/polls/ 에 접속하면 다음과 같이 Questions가 출력되는 것을 확인할 수 있다. 코드상 5개까지 출력되어야 하지만 현재 이전 시간에 만든 질문 하나밖에 없기에 하나만 출력이 되는 것을 확인할 수 있다.
view에서 페이지의 디자인을 하드코딩 하는 것 보다 뷰에서 사용할 수 있는 템플릿을 작성하고 파이썬 코드로 분리도록 django의 템플릿을 사용하자
polls/templates에 템플릿을 직접 넣게되면 다른 응용프로그램에서 같은 이름의 템플릿과 구분할 수 없기 때문에 안에 polls 디렉토리를 만들어 해당 디렉토리 안에 템플릿을 넣는다.
polls/templates/polls/index.html
{% 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 %}
위 html을 index함수에서 보여주게 하기위해 코드를 수정하자.
polls/views.py
from django.template import loader
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를 새로 import하고 index함수를 다음과 같이 수정한다. 이 코드는 polls/html 템플릿을 불러오고 context를 전달한다. index.html에서는 전달받은 context(latest_question_list
)를 화면에 띄운다.
render
를 import하면 loader
와 HttpResponse
를 import하지 않을 수 있다. render는 request객체를 첫번째 인수로 받고, 템플릿 이름을 두번째, context 사전형 객체를 세번째 선택적 인수로 받는다.
polls/view.py
from django.shortcuts import render
from .models import Question
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)