설문조사 애플리케이션에 사용될 4개의 view 를 만든다.
애플리케이션 폴더안의 Views.py에 사용자에게 보여줄 View를 작성한다.
# /workspace/Edu_02/mysite/polls/urls.py
from django.shortcuts import render
# Create your views here.
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들과 매핑될 URL을 작성해준다.
# /workspace/Edu_02/mysite/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'),
]
Question을 출판일자로 정렬하여 5개를 가져와 콤마로 연결하겠다는 내용을 Views.py에 코딩한다.
# /workspace/Edu_02/mysite/polls/urls.py
from django.http import HttpResponse
from .models import Question
# Create your views here.
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)
polls/templates/polls 폴더를 생성해준다. 장고는 이름이 일치하는 첫번째 템플릿을 선택하기 때문에 경로를 명확한 명칭으로 지정해주어야 한다.
템플릿 폴더안에 index 명령에 Response할 HTML 파일을 작성해준다.
# /workspace/Edu_02/mysite/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 %}
표시할 파일이 바뀌었으니 Views.py에서 표시할 파일을 수정해준다.
# /workspace/Edu_02/mysite/polls/views.py
from django.http import HttpResponse
from .models import Question
from django.template import loader #<< 템플릿 추가
# Create your views here.
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))
템플릿에 context 를 채워넣어 표현한 결과를 [HttpResponse](https://docs.djangoproject.com/ko/4.1/ref/request-response/#django.http.HttpResponse)
객체와 함께 돌려주는 구문은 자주 쓰는 용법이다. 따라서 Django는 이런 표현을 쉽게 표현할 수 있도록 단축 기능(shortcuts)을 제공합니다. index()
뷰를 단축 기능으로 작성하면 다음과 같다.
# /workspace/Edu_02/mysite/polls/views.py
from django.http import HttpResponse
from .models import Question
from django.shortcuts import render #<< render 사용
# Create your views here.
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 render(request, 'polls/index.html', context)
에러가 발생할 경우 미리 예외 메세지를 지정할 수 있다. 없는 URL을 입력했을 때 “Question does not exist” 메세지를 표시하게 Views.py를 수정해본다.
# /workspace/Edu_02/mysite/polls/views.py
from django.http import HttpResponse, Http404 # 404추가
from .models import Question
from django.shortcuts import render #<< render 사용
#...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
HTML 파일에는 표시만 가능하게 간단한 파일을 작성해둔다.
# /workspace/Edu_02/mysite/polls/templates/polls/detail.html
{{ question }}
실행해본다.
만약 객체가 존재하지 않을 때 get() 을 사용하여 Http404 예외를 발생시키는것은 자주 쓰이는 용법이다. Django에서 이 기능에 대한 단축 기능을 제공하는데, detail() 뷰를 단축 기능으로 작성하면 다음과 같다.
# /workspace/Edu_02/mysite/polls/views.py
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
get_object_or_404() 함수는 Django 모델을 첫번째 인자로 받고, 몇개의 키워드 인수를 모델 관리자의 get() 함수에 넘긴다. 만약 객체가 존재하지 않을 경우, Http404 예외가 발생한다.
작동은 동일하다
detail 화면을 작성해본다. 이 화면에선 context에서 question 값을 가져와서 뿌려줄 것이다. 일단 위에서 만들기만 한 detail.html을 내용이 있게 수정한다.
/workspace/Edu_02/mysite/polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
작성한 HTML파일 안에 URL들이 "/polls/{{ question.id }}/" 형식으로 고정값이 할당되어 있다. 이런경우 URL이 바뀌면 일일히 HTML 파일을 다 수정을 해주어야 한다는 어려움이 있다. 이러한 불편함을 방지하고자 urls.py에 app이름을 명시해두고 path 함수에 지정한 url의 별명을 가져다가 지정해 관리할 수 있다.
# /workspace/Edu_02/mysite/polls/urls.py
from django.urls import path
from . import views
app_name = 'polls' # << 애플리케이션 지정
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'), # << name을 가져다 사용한다
# 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'),
]
# /workspace/Edu_02/mysite/polls/templates/polls/index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}