본문으로 바로가기

안녕하세요. 메타클라우드 입니다. 😎
패스트캠퍼스 챌린지 15일차 블로그 학습 정리 포스팅입니다.

학습 기록

지난번까지 Django의 View 기능을 알아보고 테스트를 진행하였습니다. 이번 포스팅은 Django 사용자들이 실제로 웹을 통해 투표가 가능하도록 코드를 변경하는 강의를 듣고 실습내용을 정리하였습니다. 패스트캠퍼스 15일차 수강 인증샷 입니다.

패스트캠퍼스 챌린지 15일차 - 수강 인증샷

 

탬플릿에서 하드코딩된 URL 제거하기

만약 URL이 변경된다면 하드코딩된 URL이 많으면 많을수록 코드 전체를 다 바꿔야 합니다. 아래 index.html에 작성되어 있는 하드코딩 된 URL을

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

아래와 같이 바꿉니다. 그리고 urls.py에서 detail의 path를 변경해도 잘 접속되는지 확인해보겠습니다.

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

path를 바꾸기전엔 3번 페이지로 접속됨
path를 바꿔도 자동으로 바꾼 페이지로 접속됨

URL의 이름공간 정하기

튜토리얼의 프로젝트는 polls라는 앱 하나만 가지고 진행했지만 실제 Django 프로젝트는 앱이 몇개라도 올 수 있습니다. Django는 이 앱들의 URL을 어떻게 구별해 낼까요? 예를 들어, polls 앱은 detail이라는 뷰를 가지고 있고, 동일한 프로젝트에 블로그를 위한 앱이 있을 수도 있습니다. Django가 {% url %} 템플릿태그를 사용할 때, 어떤 앱의 뷰에서 URL을 생성할지 알 수 있을까요?

정답은 URLconf에 이름공간(namespace)을 추가하는 것입니다. polls/urls.py 파일에 app_name을 추가하여 어플리케이션의 이름공간을 설정할 수 있습니다.

app_name 설정
경로에 app_name 값을 지정

form 을 통해 값 입력받기

polls/detail.html을 아래와 같이 수정하여 HTML의 리스트를 라디오 버튼으로 바꿔 값을 입력받아 보겠습니다.

<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
    <legend><h1>{{ question.question_text }}</h1></legend>
    {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
    {% 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><br>
    {% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>

위의 템플릿은 각 질문 선택 항목에 대한 라디오 버튼을 표시합니다. 각 라디오 버튼의 value는 연관된 질문 선택 항목의 ID입니다. 각 라디오 버튼의 name은 "choice"입니다. 즉, 누군가가 라디오 버튼 중 하나를 선택하여 폼을 제출하면, POST 데이터 인 choice=#을 보낼 것입니다. 여기서 #은 선택한 항목의 ID입니다. 이것은 HTML 폼의 기본 개념입니다.

이제 polls/views.py 에서 아래 사항을 추가합니다.

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse

from .models import Choice, Question
# ...
def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

그럼 이제 아래와 같이 투표를 하게 되면 해당 항목의 vote 투표수가 증가 하게 됩니다.

투표 후 vote 증가

패스트캠퍼스 챌린지 15일차 포스팅을 여기서 마치며, 다음 포스팅에서는 온라인 주문 어플리케이션 벡엔드 강의를 듣고 실습 내용을 정리하겠습니다.


본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

https://bit.ly/3FVdhDa

 

수강료 100% 환급 챌린지 | 패스트캠퍼스

딱 5일간 진행되는 환급챌린지로 수강료 100% 환급받으세요! 더 늦기전에 자기계발 막차 탑승!

fastcampus.co.kr