이제 하드코딩된 <a>태그의 url을 바꾸어 보도록 하겠습니다.
/mysite/polls/templates/polls/index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
그냥 detail의 url에 question.id를 삽입해라 는 코드입니다. detail의 url이 바뀌더라도 상관이 없는 코드가 됩니다.
그리고 views.py에 app_name을 지정해 줄 수도 있습니다.
/mysite/polls/urls.py
from django.urls import path
from . import views
app_name = "polls"
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
/mysite/polls/templates/polls/index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
이렇게 하면 url을 stable하게 작성할 수 있는 것입니다.
투표기능 완성하기
이제 직접 detail.html에서 form을 만들어서 db에서 그 값을 바꿔서 question에 대한 choice의 값중 vote를 선택하면 하나씩 증가시키는 코드를 작성해보도록 하겠습니다.
/mysite/polls/views.py
from django.shortcuts import get_object_or_404, render
# from django.http import Http404
# from django.template import loader
from .models import Choice, Question
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list, }
return render(request, 'polls/index.html', context)
def detail(request, question_id):
q = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': q, })
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
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):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
/mysite/polls/templates/polls/detail.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>
뭔가 복잡해 보이지만 그렇게 복잡한 것은 아닙니다. 그냥 detail.html에서 question의 값으로 투표 기능을 해주는 form을 다음과 같이 만든 것입니다.
그리고 form의 각 name은 choice이고 id는 choice1~4가 됩니다. forloop.counter는 for문이 몇번 반복되었는지를 가리킵니다. 그리고 value는 choice.id즉 pk값이 됩니다. vote함수에서 이 값을 가지고 해당되는 choice값의 vote를 증가시켜 줄 겁니다.
vote함수에서는 pk = question_id즉 위에서 만든 form의 action은 polls:vote로 가고 question.id를 인자로 보내는데, 이에 해당하는 question을 일단 question이라는 변수에 담아옵니다. 그리고 form에서 post로 choice라는 이름으로 쏴준 값을 pk로써 question을 외래키로 하는 choice를 listup하고 이중 pk가 choice인 것을 선택하면 됩니다. 막 1개월 뒤를 클릭하면 이 choice가 선택된 것이라고 보시면 됩니다.
그리고 가려낸 choice의 vote값을 1증가시켜주고 이를 저장해 주고 polls:results로 쏴주고 question.id를 인자로써 쏴주면 아래와 같게 됩니다.
위에서 1개월 뒤를 선택하면 polls:results로 redirect되고, admin panel에서 choice테이블의 1개월 뒤의 변화된 값을 보면 votes가 0에서 1로 1증가한 것을 보실 수 있습니다.
'DevOps > AWS Architecture' 카테고리의 다른 글
[ DevOps ] - AWS 기반 소규모 & 중규모 아키텍트 설계 - Order백엔드 개발 1 (0) | 2022.06.29 |
---|---|
[ DevOps ] - AWS 기반 소규모 & 중규모 아키텍트 설계 - Models 제작 (0) | 2022.06.28 |
[ DevOps ] - AWS 기반 소규모 & 중규모 아키텍트 설계 - Django 기초 - 2 (0) | 2022.06.28 |
[ DevOps ] - AWS 기반 소규모 & 중규모 아키텍트 설계 - Django 기초 - 1 (0) | 2022.06.28 |
[ DevOps ] - AWS 기반 소규모 & 중규모 아키텍트 설계 - 어플리케이션 이벤트 스토밍 (0) | 2022.06.28 |