DetailView, IndexView, ResultsView
기존의 DetailView는 html 형태로 데이터를 리턴함
class DetailView(generic.DetailView):
model = Question
template_name = "polls/detail.html"

get 요청시 model로 필요한 데이터를 받아오고, json 형태로 변환하여 리턴하도록 DetailView를 변경
- Question 테이블에 특정 id의 데이터가 없으면 404 error 발생하도록 처리
class DetailView(View):
def get(self, request, pk):
question_with_choice = get_object_or_404(Question.objects.prefetch_related('choice_set'), pk=pk)
choices = list(question_with_choice.choice_set.all().values('id', 'choice_text'))
question_dict = model_to_dict(question_with_choice)
question_dict['polls_choice'] = choices
response = json.dumps(question_dict, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')

IndexView, ResultsView도 json 형태로 데이터를 리턴하도록 변경
class IndexView(View):
def get(self, request):
all_questions = Question.objects.all()
data_list = []
for obj in all_questions:
data_list.append(model_to_dict(obj))
response = json.dumps(data_list, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
class DetailView(View):
def get(self, request, pk):
question_with_choice = get_object_or_404(Question.objects.prefetch_related('choice_set'), pk=pk)
choices = list(question_with_choice.choice_set.all().values('id', 'choice_text'))
question_dict = model_to_dict(question_with_choice)
question_dict['polls_choice'] = choices
response = json.dumps(question_dict, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
class ResultsView(generic.DetailView):
def get(self, request, pk):
question_with_choice = get_object_or_404(Question.objects.prefetch_related('choice_set'), pk=pk)
choices = list(question_with_choice.choice_set.all().values('id', 'choice_text', 'votes'))
question_dict = model_to_dict(question_with_choice)
question_dict['polls_choice'] = choices
response = json.dumps(question_dict, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
vote
post 요청을 받으면, choice_id의 votes에 1을 추가하고 {"message": "voted"}를 리턴하도록 변경
@csrf_exempt
def vote(request, question_id):
if request.method == 'POST':
question = get_object_or_404(Question, pk=question_id)
try:
# { "choice_id": 1 }
data = json.loads(request.body)
selected_choice = question.choice_set.get(pk=data["choice_id"])
except (KeyError, Choice.DoesNotExist, json.JSONDecodeError):
return JsonResponse({"error": "Invalid choice"}, status=400)
else:
selected_choice.votes = F("votes") + 1
selected_choice.save()
return JsonResponse({"message": "voted"}, status=201)
choice_id를 4로 해서 post 요청을 하면, voted 메시지를 요청 받음

polls_choice 테이블 확인해보면, 선택한 id의 votes가 1 증가함

views.py 전체 코드
from django.db.models import F
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import View, generic
from django.core.serializers.json import DjangoJSONEncoder
from django.forms.models import model_to_dict
from django.views.decorators.csrf import csrf_exempt
import json
from .models import Choice, Question
class IndexView(View):
def get(self, request):
all_questions = Question.objects.all()
data_list = []
for obj in all_questions:
data_list.append(model_to_dict(obj))
response = json.dumps(data_list, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
class DetailView(View):
def get(self, request, pk):
question_with_choice = get_object_or_404(Question.objects.prefetch_related('choice_set'), pk=pk)
choices = list(question_with_choice.choice_set.all().values('id', 'choice_text'))
question_dict = model_to_dict(question_with_choice)
question_dict['polls_choice'] = choices
response = json.dumps(question_dict, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
class ResultsView(generic.DetailView):
def get(self, request, pk):
question_with_choice = get_object_or_404(Question.objects.prefetch_related('choice_set'), pk=pk)
choices = list(question_with_choice.choice_set.all().values('id', 'choice_text', 'votes'))
question_dict = model_to_dict(question_with_choice)
question_dict['polls_choice'] = choices
response = json.dumps(question_dict, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
@csrf_exempt
def vote(request, question_id):
if request.method == 'POST':
question = get_object_or_404(Question, pk=question_id)
try:
# { "choice_id": 1 }
data = json.loads(request.body)
selected_choice = question.choice_set.get(pk=data["choice_id"])
except (KeyError, Choice.DoesNotExist, json.JSONDecodeError):
return JsonResponse({"error": "Invalid choice"}, status=400)
else:
selected_choice.votes = F("votes") + 1
selected_choice.save()
return JsonResponse({"message": "voted"}, status=201)
응답 결과
IndexView

DetailView

ResultsView

'Language > Python' 카테고리의 다른 글
[Python] Django 투표 앱과 frontend 연결하기 (0) | 2024.12.17 |
---|---|
[Python] Django Model, View 사용하기 (0) | 2024.12.17 |
[Python] Django 투표 앱 만들기 (2) (0) | 2024.12.17 |
[Python] Django 투표 앱 만들기 (1) (1) | 2024.12.17 |
[Python] Django 프로젝트 생성하기 (1) | 2024.12.17 |