vote를 눌렀을 때 해당 정보로 넘어가게 해요!
기본적으로 현재 질문이 무엇인지 서버 쪽에 넘어가야 해요.
1. 뭐가 전달돼야 가능할까? 지금 어떤 question 항목을 가지고 진행되고 있는지?
pk로 server 쪽 항목으로 전달
2. question 항목에 대해 어떤 항목을 선택했는지? form, post
key valie 형태로.
vote 버튼을 눌렀을 때 어떻게 request가 가는지 알아보아요.
url conf 로 가서 view를 호출해야 해요.
/polls/id/vote →post방식으로 view 서버 쪽에 request가 보내요.
polls 폴더 detail.html
url을 표현하는 방법
1. <form action="http://localhost:8000/polls/{{question.id}}/vote/"
이렇게 해도 돼요
2.<form action="{% url 'polls:detail'% question_id}"
보통 이렇게 많이 쓰고 더 편해요!
polls urls.py 에 가보면
name='index' , name='detail'가 있는데 다른 애플리케이션에도 같은 이름이 있을 수 있기 때문에
namespace 가 있는 거예요 → add_name = 'polls'
주소에 맞게 순서로대로 적어주면 돼요!
<title>Title</title>
<!-- <form action="http://localhost:8000/polls/{{question.id}}/vote/-->
<!-- 이렇게 해도 돼요!-->
<h1>{{ question.question_text }}</h1>
<form action="{% url 'polls:vote' question_id}"
method="POST">
{% csrf_token %}
urls.py
vote라는 새로운 serval 쪽 url을 사용할 거예요.
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
# http://localhost:8000/polls/
path('', views.index, name='index'),
# http://localhost:8000/polls/2/
path('<int:question_id>/', views.detail, name='detail'),
# http://localhost:8000/polls/2/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
# http://localhost:8000/polls/2/results/
path('<int:question_id>/results/', views.results, name='results')
]
views.py
views.py 가서 새로운 함수를 지정해 줘요.
2가지 경우가 있어요!
하나는 정상적으로 항목을 선택해서 투표하는 경우.
또 하나는 어떠한 것도 선택하지 않은 상황에서 투표 버튼을 클릭하는 경우.
예외 상황이 발생했을 때 특별한 처리를 하기 위해 try를 쓸 거예요. 현재 내가 선택한 choice에 대한 instance를 가져오는 코드를 쓸 거예요. get()
detail.html의 id 값을 가져온 거예요 request로부터 post 방식으로 넘어왔기 때문
key 값 myChoice를 입력하면 value choice.id 가 들어와요
항상 name=value로 가져와요 id= choice는 radio와 mapping(일치시키기) 위해 사용하는 거예요.
choice = question.choice_set.get(pk=request.POST['myChoice'])
객체가 저장되어 있는 database table을 저장시켜줍니다. choice.save()
이제 3번째 화면을 출력하면 돼요!(여기서 하지 않아요 redirection 해서 처리할 거예요)
이 기능을 새로운 request를 이용해서 새로운 view 함수를 이용해서 처리할 거예요.
redirect → URL을 만들어서 클라이언트에게 결과로 전달하고 클라이언트는 이 URL로 서버에 다시 접속해요.
HttpResponseRedirect 은 해당 URL을 가지고 다시 접속하라는 의미예요.
url을 namespace와 name으로 url conf에서 찾아오는 코드 방법은 다음과 같아요!
args= 는 값을 넘겨줄 때 튜플로 표현해 줘요! 인자가 하나밖에 없으니 , 뒤에 비워줘요.
from django.shortcuts import render, get_object_or_404
from polls.models import Question, Choice
from django.http import HttpResponseRedirect
from django.urls import reverse
def vote(request, question_id):
# 2가지 경우가 있어요! 하나는 정상적으로 항목을 선택해서 투표하는 경우
# 또 하나는 어떠한 것도 선택하지 않은 상황에서 투표 버튼을 클릭하는 경우
question = get_object_or_404(Question, pk=question_id)
try:
choice = question.choice_set.get(pk=request.POST['myChoice'])
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'err_msg': '아무것도 선택하지 않았어요!'
})
else:
# 정상적인 상황이기 때문에 해당 항목에 대한 투표수를 증가시켜요!
# 최종 화면에 대한 request를 생성해서 보내요!
choice.votes += 1
choice.save()
# 3번째 화면을 출력하면 돼요!(여기서!( 하지 않아요 redirection 해서 처리할 거예요)
# 이 기능을 새로운 request를 이용해서 새로운 View함수를 이용해서 처리할 거예요!
# url을 표현하기 위해서 직접 입력하는 방법이 있고요(쉬워요)
# url을 namespace와 name으로 url conf에서 찾아오는 코드 방법은 다음과 같아요!
# /polls/id/results
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
def results(request, question_id):
# 마지막 3번째 화면(투표 결과 화면)을 만들어서 리턴해요!
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {
'question': question
})
polls 폴더에 html 파일을 하나 만들어봅시다.
results.html
{% for choice in question_choice_set.all %} 템플릿 언어에서는 choice_set.all 뒤에 () 쓰지 않아요.
<body>
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} - {{ choice.votes }} 표</li>
{% endfor %}
</ul>
<a href="{% url 'polls:index' %}"> 질문 선택 화면으로 돌아가기 </a>
</body>
'Back end' 카테고리의 다른 글
0728 Django 게시판만들기 (0) | 2021.07.28 |
---|---|
0722 Django project2 (0) | 2021.07.22 |
0721 Pycharm 설정 (0) | 2021.07.21 |
0720 Django 프로젝트 만들기 (0) | 2021.07.20 |
0720 Django (0) | 2021.07.20 |
댓글