본문 바로가기
Back end

0723 Django project3

by 대금부는개발자 2021. 7. 23.
SMALL

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>

LIST

'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

댓글