polls ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ 3๊ฐ์ ํ์ด์ง๊ฐ ํ์ํ๋ค. ์ด๋ฅผ ์ํ ๋ทฐ์ ํ ํ๋ฆฟ์ ์ฝ๋ฉํ๋ค.
URL๊ณผ ๋ทฐ๋ 1:1 ๊ด๊ณ๋ก ๋งคํ๋๋ค. ์ด๋ฌํ URL/๋ทฐ ๋งคํ์ URLconf๋ผ๊ณ ํ๋ฉฐ urls.py ํ์ผ์ ์์ฑํ๋ค.
์ด ์ค๊ณ ๋ด์ฉ์ ๊ฐ๋ฐํ๊ธฐ ์ํด ์๋ ์์๋๋ก ์ฝ๋ฉ์ ์งํํ๋ค. ๋ก์ง์ ํ๋ฆ์ URLconf๋ฅผ ๋จผ์ ์ฝ๋ฉํ ํ์ ๋ทฐ, ํ ํ๋ฆฟ ๋๋ ํ ํ๋ฆฟ, ๋ทฐ ์์๋ก ์ฝ๋ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
Admin ์ฌ์ดํธ ํฌํจ 5๊ฐ์ URL๊ณผ ๋ทฐ๊ฐ ํ์ํ๋ค.
urls.py
from django.contrib import admin
from django.urls import path
from polls import views
# URL ํจํด ๋งค์นญ์ ์์์ ์๋๋ก ์งํํ๋ฏ๋ก, ์ ์ํ๋ ์์ ์ ์
urlpatterns = [
path('admin/', admin.site.urls),
path('polls/', views.index, name='index'),
path('polls/<int:question_id>/', views.detail, name='detail'),
path('polls/<int:question_id>/results/', views.results, name='results'),
path('polls/<int:question_id>/vote/', views.vote, name='vote'),
]
path() ํจ์๋ route, view 2๊ฐ์ ํ์ ์ธ์์ kwargs, name 2๊ฐ์ ์ ํ ์ธ์๋ฅผ ๋ฐ๋๋ค.
๋ง์ผ URL์ด /polls/3/ ์ด๋ผ๋ฉด URL ์คํธ๋ง์์ 3์ด ์ถ์ถ๋๋ฏ๋ก ๋ทฐ ํจ์๋ฅผ ํธ์ถ ์ views.detail(request, question_id=3)์ฒ๋ผ ์ธ์๊ฐ ๋์ ๋๋ค.
mystie/settings.py ํ์ผ์ ROOT_URLCONF ํญ๋ชฉ์ด ์ ์๋๋ค. ์ฅ๊ณ ๋ URL ๋ถ์ ์, ์ด ํญ๋ชฉ์ ์ ์๋ urls.y ํ์ผ์ ๊ฐ์ฅ ๋จผ์ ๋ถ์ํ๊ธฐ ์์ํ๋ค.
URLconf๋ฅผ ์ฝ๋ฉํ ๋ ์์์์ฒ๋ผ ํ๋์ urls.py ํ์ผ์ ์์ฑํ ์๋ ์๊ณ ๋ค์๊ณผ ๊ฐ์ด mysite/urls.py์ polls/urls.py 2๊ฐ์ ํ์ผ์ ์์ฑํ ์๋ ์๋ค.
mysite/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('polls/', include('polls.urls')),
]
polls/urls.py
from django.urls import path
from polls import views
# URL ํจํด์ ์ด๋ฆ์ด ์ถฉ๋๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํ ์ด๋ฆ ๊ณต๊ฐ
app_name = 'polls'
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'),
]
์ด๋ ๊ฒ URLconf ๋ชจ๋์ ๊ณ์ธต์ ์ผ๋ก ๊ตฌ์ฑํ๋ ๊ฒ์ด ๋ณ๊ฒฝ๋ ์ฌ์์ง๊ณ ํ์ฅ๋ ์ฉ์ดํด์ง๊ธฐ ๋๋ฌธ์ ๋ ์ข๋ค.
UI ํ๋ฉด์ ์๊ฐํ๋ฉด์ ๋ก์ง์ ํ์ด๋๊ฐ๋ ๊ฒ์ด ์ฝ๊ธฐ ๋๋ฌธ์ ๋ทฐ๋ณด๋ค ํ ํ๋ฆฟ์ ๋จผ์ ์ฝ๋ฉํ๋ ๊ฒ์ด ์ข๋ค.
index.html
{% if latest_question_list %}
<!--latest_question_list ๊ฐ์ฒด๋ index() ๋ทฐ ํจ์์์ ๋๊ฒจ์ฃผ๋ ํ๋ผ๋ฏธํฐ์ด๋ค.-->
<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 %}
index.html์ ์์ฑํ๋ฉด์ ํ์ํ ๋ณ์๊ฐ ๋ฌด์์ธ์ง ์ฐพ์๋ด์ผ ํ๋ค. ์ด ๋ณ์๋ ๋ทฐ ํจ์์์ context ๋ณ์๋ก ์ ์ํด์ ํ ํ๋ฆฟ์ผ๋ก ๋๊ฒจ์ค์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์์ ์ ํ ํ๋ฆฟ์์๋ ์ง๋ฌธ์ผ๋ก ์ฌ์ฉ๋ ์ฌ๋ฌ ๊ฐ์ question_text๋ฅผ ํ๋ฉด์ ๋ณด์ฌ์ค์ผ ํ๊ณ URL ๋งํฌ๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ์ํด question.id๋ ํ์ํ๋ค. ์ด ๋ ๊ฐ์ง ์ ๋ณด๊ฐ ํจ๊ป ๋ค์ด์๋ Question ๊ฐ์ฒด๋ฅผ ๋ทฐ ํจ์๋ก๋ถํฐ ๋๊ฒจ๋ฐ์ผ๋ฉด ๋๋ค. Question ๊ฐ์ฒด๋ค์ ๋ฆฌ์คํธ๊ฐ ๋ค์ด์๋ latest_question_list ๋ณ์๋ฅผ ๋ทฐ ํจ์๋ก๋ถํฐ ํ ํ๋ฆฟ ํ์ผ๋ก ์ ๋ฌํด์ผ ํ๋ค.
from django.shortcuts import render # ๋จ์ถํจ์ render import
from polls.models import Question
def index(request):
# Question ํ
์ด๋ธ ๊ฐ์ฒด์์ pub_date ์ปฌ๋ผ์ ์ญ์์ผ๋ก ์ ๋ ฌํ์ฌ
# 5๊ฐ์ ์ต๊ทผ Question ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์์ ๋ง๋ ๋ค.
latest_question_list = Question.objects.all().order_by('-pub_date')[:5]
# ํ
ํ๋ฆฟ์ ์ฌ์ฉ๋ ๋ณ์๋ช
๊ณผ ๊ทธ ๋ณ์๋ช
์ ํด๋น๋๋ ๊ฐ์ฒด๋ฅผ ๋งคํํ๋ ์ฌ์ ํ์
์ผ๋ก
# context ๋ณ์๋ฅผ ๋ง๋ค์ด ์ด๋ฅผ render() ํจ์์ ๋ณด๋ด์ค๋ค.
context = {'latest_question_list': latest_question_list}
# render() ํจ์๋ ํ
ํ๋ฆฟ ํ์ผ์ธ polls/index.html์ context ๋ณ์๋ฅผ ์ ์ฉํ์ฌ
# ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค ์ต์ข
HTML์ ๋ง๋ค๊ณ ์ด๋ฅผ ๋ด์ HttpResponse ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
return render(request, 'polls/index.html', context)
๋จ์ถํจ์๋?
์น ํ๋ก๊ทธ๋จ ๊ฐ๋ฐ ์ ์์ฃผ ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ๋ค, ์๋ฅผ ๋ค์ด render() ํจ์์ฒ๋ผ ํ ํ๋ฆฟ ์ฝ๋๋ฅผ ๋ก๋ฉํ ํ์ ์ปจํ ์คํธ ๋ณ์๋ฅผ ์ ์ฉํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ HTTPResponse ๊ฐ์ฒด์ ๋ด์ ๋ฐํํ๋ ์์ ๋ฑ์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ๋ค์ ์ฅ๊ณ ์์๋ ์ด๋ฏธ ๊ฐ๋ฐํ์ฌ ๋ด์ฅ ํจ์๋ก ์ ๊ณตํ๊ณ ์๋๋ฐ ์ด๋ฅผ ๋จ์ถํจ์๋ผ๊ณ ํ๋ค.
์ฅ๊ณ ์์ ํ ํ๋ฆฟ ํ์ผ์ ์ฐพ์ ๋ TEMPLATES, INSTALLED_APP์์ ์ง์ ๋ ๋๋ ํ ๋ฆฌ๋ฅผ ๊ฒ์ํ๋๋ฐ ์ด ์ค INSTALLED_APPS ํญ๋ชฉ์ ๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ํ ํ๋ฆฟ ํ์ผ์ ์์น๋ ์ฃผ์ํ ๊ฒ์ด ์๋ค.
์ ํ๋ฆฌ์ผ์ด์ ๊ฐ์๊ฐ ๋์ด๋๊ณ ํ ํ๋ฆฟ ํ์ผ์ด ๋ง์์ง๋ฉด ์ด๋ฆ์ด ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ templates ๋๋ ํ ๋ฆฌ ํ์์ ๋ค์ ์ ํ๋ฆฌ์ผ์ด์ ๋ช ์ผ๋ก ๋๋ ํ ๋ฆฌ๋ฅผ ๋ง๋ค์ด ํ ํ๋ฆฟ ํ์ผ์ ์์น์ํค๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
ch3/polls/templates/polls/index.html
ch3/polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" \
value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
{% endfor %}
<input type="submit" value="Vote" />
</form>
์ฝ๋ ์ค๋ช
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
์๋ฌ๋ฅผ ์ฒดํฌํ๋ ๋ก์ง์ ๋ค์ ์ ์ vote() ๋ทฐ ํจ์์ ์๋ค.
vote() ๋ทฐ ํจ์์์ ์ต์
์
์ด ๋ฐ์ํ๋ฉด error_message๋ฅผ ๋ด์
detail.html ํ
ํ๋ฆฟ์ ๋ ๋๋งํ๊ณ , ๊ทธ์ ๋ฐ๋ผ ์ง๊ธ์ detail.html ํ
ํ๋ฆฟ์์
์๋ฌ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ค๋ค.
<form action="{% url 'polls:vote' question.id %}" method="post">
์๋ฒ ์ธก์์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋ก POST ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
< form action> ์์ฑ์ {% url %} ํ ํ๋ฆฟ ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ ๊ณณ์ URL์ polls:vote๋ก ์ง์ ํ๋ค. polls:vote๋ URLconf์์ ์ ์ํ URL ํจํด ์ด๋ฆ์ด๋ค. ๋์ผํ ์ผ๋ฏ์ผ๋ก ์ธํ ์ถฉ๋์ ๋ง๊ธฐ ์ํด ์ด๋ฆ ๊ณต๊ฐ์ ์ถ๊ฐํด์ polls:vote๊ฐ ๋ ๊ฒ์ด๋ค.
{% for choice in question.choice_set.all %}
for ํ๊ทธ๋ก ๋ทฐ ํจ์์์ ๋์ด์จ ๊ฐ์ฒด๋ฅผ ์ํํ๋ค. question.choice_set.all์ ์๋ฏธ๋ Question ๊ฐ์ฒด์ choice_set ์์ฑ์ ๋ค์ด์๋ ํญ๋ชฉ ๋ชจ๋๋ฅผ ๋ปํ๋ค.
<input type="radio" name="choice" id="choice{{ forloop.counter }}" \
value="{{ choice.id }}" />
๋ผ๋์ค ๋ฒํผ์ผ๋ก ๋ต๋ณ ํญ๋ชฉ์ ๋ณด์ฌ์ค๋ค. ํด๋น ๋ผ๋์ค ๋ฒํผ์ ์ ํํ๋ฉด POST ๋ฐ์ดํฐ๊ฐ 'choice'='3' ํํ๋ก ๊ตฌ์ฑ๋๋๋ก name๊ณผ value ์์ฑ์ ์ ์ํ๋ค.
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
forloop.counter ๋ณ์๋ for ๋ฃจํ๋ฅผ ์คํํ ํ์๋ฅผ ๋ด๊ณ ์๋ ๋ณ์์ด๋ค. label for ์์ฑ๊ณผ input id ์์ฑ์ ๊ฐ์ด ๊ฐ์์ผ ์๋ก ๋ฐ์ธ๋ฉ๋๋ค.
<input type="submit" value="Vote" />
Vote ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ฌ์ฉ์๊ฐ ์ ํํ ํผ ๋ฐ์ดํฐ๊ฐ POST ๋ฐฉ์์ผ๋ก polls:vote URL๋ก ์ ์ก๋๋ค. ์ ์ก๋ ๋ฐ์ดํฐ๋ vote() ๋ทฐ ํจ์์์ request.POST['choice'] ๊ตฌ๋ฌธ์ผ๋ก ์์ธ์คํ๋ค. input ํ๊ทธ์ name๊ณผ value ์์ฑ๊ฐ๋ค์ด request.POST ์ฌ์ ์ key, value๋ก ์ฌ์ฉ๋๋ค๋ ์ ์ ์ ์ํด์ผ ํ๋ค.
Question๊ณผ Choice ํ ์ด๋ธ์ ๊ด๊ณ๋ 1:N ๊ด๊ณ์ด๊ณ , ์ธ๋ํค๋ก ์ฐ๊ฒฐ๋์ด ์๋ค. ์ฆ, question.choice_set.all() ์ด๋ผ๊ณ ํ๋ฉด Question ํ ์ด๋ธ์ question ๋ ์ฝ๋์ ์ฐ๊ฒฐ๋ Choice ํ ์ด๋ธ์ ๋ ์ฝ๋ ๋ชจ๋๋ฅผ ๋ปํ๋ค.
detail.html ํ์ผ์์ ํ์ํ ๋ณ์, ์ฆ detail() ๋ทฐ ํจ์์์ ์ ์ํด์ผ ํ context ๋ณ์๊ฐ ์ด๋ค ๊ฒ ์๋์ง ์ฐพ์๋ณด์
question.text, error_message, question.id, question.choice_set, forloop.counter, choice.id, choice.choice_text ๋ฑ์ ๋ณ์๋ค์ด ์ฌ์ฉ๋๊ณ ์๋ค.
forloop.counter : ์ฅ๊ณ ์์ ์ ๊ณตํ๋ฏ๋ก ์ ์ํ ํ์ ์๋ค.
error_message : vote() ํจ์์์ ์ ์ํ ์์
question.text, question.id, question.choice_set : ๊ฐ๊ฐ context ๋ณ์๋ก ์ ์ํด๋ ๋์ง๋ง question ๋ณ์๋ง ์ ์ํ๋ฉด ๊ทธ ๋ณ์์ ์์ฑ์ผ๋ก ์์ธ์คํ ์ ์๋ค.
choice.id, choice.choice_text : question.choice_set ๋ณ์๊ฐ ์ ์๋๋ฉด ์์ธ์ค ๊ฐ๋ฅํ๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก detail() ๋ทฐ ํจ์์์ ์ ์ํด์ผ ํ ๋ณ์๋ question ๋ณ์ ํ๋ ๋ฟ์ด๋ค.
์ด๋ ๊ฒ html ํ์ผ์ ๋จผ์ ์ฝ๋ฉํ๋ฉด์ context ๋ณ์๋ฅผ ์ฐพ๋ ์์ผ๋ก ์์งํ๋ ๊ฒ์ด ์ข๋ค.
index.html ํ๋ฉด์์ ์ง๋ฌธ ํ๋๋ฅผ ์ ํํ๋ฉด /polls/1/๊ณผ ๊ฐ์ URL์ด ๋์ด์ค๊ฒ ๋์ด ์๋ค.
index.html์ ์๋ ์ฝ๋๋ฅผ ๋ปํ๋ค.
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
๋ํ urls.py์์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ๋ค.
path('<int:question_id>/', views.detail, name='detail'),
์ ๋ ๋ผ์ธ์ ์ํด ์ง๋ฌธ ํ๋๋ฅผ ์ ํํ๋ฉด detail() ๋ทฐ ํจ์๊ฐ ํธ์ถ๋๋ ๊ฒ์ด๋ค.
์ด์ views.py์ deatil()์ ์์ฑํ๋ค.
# ๋ทฐ ํจ์๋ฅผ ์ ์ํ๋ค. request ๊ฐ์ฒด๋ ํ์ ์ธ์์ด๊ณ , ์ถ๊ฐ์ ์ผ๋ก question_id ์ธ์๋ฅผ
# ๋ ๋ฐ๋๋ค. URL ํจํด์ผ๋ก๋ถํฐ ์ถ์ถ๋ question_id๊ฐ ๋ทฐ ํจ์์ ์ธ์๋ก ๋์ด์จ๋ค.
def detail(request, question_id):
# get_object_or_404() ๋จ์ถํจ์
question = get_object_or_404(Question, pk=question_id)
# ํ
ํ๋ฆฟ์๊ฒ ๋๊ฒจ์ฃผ๋ ์ปจํ
์คํธ ์ฌ์ ์ render() ํจ์์ ์ธ์๋ก ์ง์ ์จ์ฃผ๊ณ ์๋ค.
# ํ
ํ๋ฆฟ ํ์ผ์์๋ question์ด๋ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๊ฒ์ด๋ค.
return render(request, 'polls/detail.html', {'question':question})
get_object_or_404() : ์ด ํจ์์ ์ฒซ ๋ฒ์งธ ์ธ์๋ ๋ชจ๋ธ ํด๋์ค์ด๊ณ , ๋ ๋ฒ์งธ ์ธ์๋ถํฐ ๊ฒ์ ์กฐ๊ฑด์ ์ฌ๋ฌ ๊ฐ ์ฌ์ฉํ ์ ์๋ค. ์ด ์์ ์์๋ Question ๋ชจ๋ธ ํด๋์ค๋ก๋ถํฐ pk=question_id ๊ฒ์ ์กฐ๊ฑด์ ๋ง๋ ๊ฐ์ฒด๋ฅผ ์กฐํํ๋ค. ์กฐ๊ฑด์ ๋ง๋ ๊ฐ์ฒด๊ฐ ์์ผ๋ฉด Http404 ์ต์ ์ ์ ๋ฐ์์ํจ๋ค.
vote() ๋ทฐ ํจ์์ ํธ์ถ๊ณผ ์ฐ๊ณ๋ URL์ detail.html ํ ํ๋ฆฟ ํ์ผ์์ ๋ฐ๋๋ค. ์ฆ, detail.html ํ ํ๋ฆฟ์ ์๋ ํผ์ ์ ์ถํ๋ฉด ํผ์ ๊ธฐ๋ฅ์ ์ํด /polls/5/vote/์ ๊ฐ์ URL์ด POST ๋ฐฉ์์ผ๋ก ๋์ด์จ๋ค.
detail.html์ form ๋ถ๋ถ
<form action="{% url 'polls:vote' question.id %}" method="post">
urls.py์ vote ๋ถ๋ถ
path('<int:question_id>/vote/', views.vote, name='vote'),
์ ๋ ๋ผ์ธ์ ์ํด ์ฌ์ฉ์๊ฐ Vote ๋ฒํผ์ ๋๋ฅด๋ฉด vote() ๋ทฐ ํจ์๊ฐ ํธ์ถ๋๋ค.
form์ผ๋ก๋ถํฐ ์์ ํ POST ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ vote() ๋ทฐ ํจ์๋ฅผ views.py ํ์ผ์ ์์ฑํ๋ค.
def vote(request, question_id):
# Choice ํ
์ด๋ธ์ ๊ฒ์ํ๋ค. request.POST๋ ์ ์ถ๋ ํผ์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋
# ๊ฐ์ฒด๋ก์ key๋ก ๊ทธ ๊ฐ์ ๊ตฌํ ์ ์๋ค.
# request.POST['choice']๋ ํผ ๋ฐ์ดํฐ์์ ํค๊ฐ 'choice'์ ํด๋นํ๋ ๊ฐ์ธ
# choice.id๋ฅผ ์คํธ๋ง์ผ๋ก ๋ฆฌํดํ๋ค.
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
# 'choice'๋ผ๋ ํค๊ฐ ์์ผ๋ฉด KeyError ์ต์
์
๋ฐ์
# ๊ฒ์ ์กฐ๊ฑด์ ๋ง๋ ๊ฐ์ฒด๊ฐ ์์ผ๋ฉด Choice.DoesNotExist ์ต์
์
๋ฐ์
except (KeyError, Choice.DoseNotExist):
# ์ต์
์
์ด ๋ฐ์ํ๋ฉด render() ํจ์์ ์ํด question๊ณผ error_message
# ์ปจํ
์คํธ ๋ณ์๋ฅผ detail.html ํ
ํ๋ฆฟ์ผ๋ก ์ ๋ฌ
# ์๋ฌ ๋ฉ์ธ์ง์ ํจ๊ป ์ง๋ฌธ ํญ๋ชฉ ํผ์ ๋ค์ ๋ณด์ฌ์ค์ ์ฌ์
๋ ฅํ ์ ์๋๋ก ํจ
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice",
})
else:
selected_choice.votes += 1
# ๋ณ๊ฒฝ ์ฌํญ Choice ํ
์ด๋ธ ์ ์ฅ
selected_choice.save()
# POST ๋ฐ์ดํฐ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ์ผ๋ฉด
# ํญ์ HttpResponseRedirect๋ฅผ ๋ฐํํ์ฌ ๋ฆฌ๋ค์ด๋ ์
์ฒ๋ฆฌ
# ์ต์ข
์ ์ผ๋ก vote() ๋ทฐ ํจ์๋ ๋ฆฌ๋ค์ด๋ ํธํ ํ๊ฒ URL์ ๋ด์
# HttpResponseRedirect ๊ฐ์ฒด ๋ฐํ
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
vote() ๋ทฐ ํจ์๊ฐ ๋ฐํํ๋ ๊ฐ์ฒด๋ HttpResponseRedirect ๊ฐ์ฒด์ด๋ค. HttpResponseRedirect ํด๋์ค์ ์์ฑ์๋ ๋ฆฌ๋ค์ด๋ ํธํ ํ๊ฒ URL์ ์ธ์๋ก ๋ฐ๊ณ ํ๊ฒ URL์ reverse() ํจ์๋ก ๋ง๋ ๋ค.
์ด์ฒ๋ผ POST ๋ฐฉ์์ ํผ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค ์ ์๋ ํ์ด์ง๋ก ์ด๋์ํค๊ธฐ ์ํด HttpResponseRedirect ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
URLconf๋ ์ผ๋ฐ์ ์ผ๋ก URL ์คํธ๋ง๊ณผ ๋ทฐ๋ฅผ ๋งคํํ ๊ฐ ๋ผ์ธ์ URL ํจํด์ด๋ผ ํ๊ณ ์ด๋ฆ์ ํ๋์ฉ ๋ถ์ฌํ๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ ๋ฐ๋๋ก reverse() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ URL ํจํด๋ช ์ผ๋ก๋ถํฐ URL ์คํธ๋ง์ ๊ตฌํ ์๋ ์๋ค.
reverse() ํจ์์ ์ธ์๋ก URL ํจํด์ ์ด๋ฆ๊ณผ URL ์คํธ๋ง์ ์ฌ์ฉ๋ ํ๋ผ๋ฏธํฐ, 2๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋๋ค.
reverse() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ URL์ ๊ตฌํ๋ ๊ฒ์ URLconf์ ์ด๋ฏธ ์ ์๋ URL ํจํด์ ํ์ฉํด์ URL ์คํธ๋ง์ ์ถ์ถํ๋ ๋ฐฉ์์ด๋ฏ๋ก, ์์ค์ URL ์คํธ๋ง์ ํ๋์ฝ๋ฉํ์ง ์๋๋ก ํด์ค๋ค.
๋ฆฌ๋ค์ด๋ ํธํ๋ผ๋ ์๋ต์ ๋ฐ์ ์น ๋ธ๋ผ์ฐ์ ๋ ๋ฆฌ๋ค์ด๋ ํธ URL๋ก ๋ค์ ์์ฒญ์ ๋ณด๋ธ๋ค.
urls.py์ results ๋ถ๋ถ
path('<int:question_id>/results/', views.results, name='results'),
๋ฆฌ๋ค์ด๋ ํธ ์์ฒญ๊ณผ ์ ๋ผ์ธ์ ์ํด results() ๋ทฐ ํจ์๊ฐ ํธ์ถ๋๋ค.
results() ๋ทฐ ํจ์์ ํผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ก์ง์ ์์ฑํ๋ค. ์ด๋ฒ์ ๋ทฐ -> ํ ํ๋ฆฟ ์์ผ๋ก ์ฝ๋ฉํด๋ณธ๋ค.
views.py ํ์ผ์ results() ๋ทฐ ํจ์๋ฅผ ์์ฑํ๋ค.
def resutls(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
results.html UI
results.html
<h1>{{ question.question_text }}</h1>
<ul>
<!-- ๋ทฐ ํจ์์์ ๋์ด์จ question ๋ณ์๋ฅผ ์ด์ฉํด Choice ๊ฐ์ฒด๋ฅผ ์ํ-->
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id %}">Vote again</a>
ํฅ๋ฏธ๋ก์ด ์ ์ ๋ทฐ ํจ์์ ํ ํ๋ฆฟ ํ๊ทธ ์์ชฝ์์ ๋ชจ๋ URL ์คํธ๋ง์ ์ถ์ถํ ์ ์๋ค๋ ๊ฒ์ด๋ค. ๋ทฐ ํจ์์์๋ reverse() ํจ์๋ฅผ ์ฌ์ฉํ๊ณ ํ ํ๋ฆฟ์์๋ {% url %} ํ๊ทธ๋ฅผ ์ฌ์ฉํ๋ค.
์ถ์ฒ: Django๋ก ๋ฐฐ์ฐ๋ ํ์ด์ฌ ์น ํ๋ก๊ทธ๋๋ฐ(๊ธฐ์ด) - ๊น์ํ๋