template/mydjango/detail.html로 돌아가 코드를 작성한다.
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
question.question_text를 제목으로 출력하고,
for문에서 choice.choice_text를 list로 출력해주도록 작성된 코드이다.
template에서 하드코딩된 url 제거하기.
아래는 templates/mydjango/index.html의 코드이다.
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/mydjango/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
링크 거는 코드에 url이 하드코딩되어있다.
하드코딩되어있으면 나중에 수정할 때나 여러가지 상황에서 문제 발생의 여지가 있으므로, 없애는 것이 좋다.
urls.py에서 url을 정의해둔 것이 있으므로 가져다 쓸 수 있다.
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
만약 상세 url을 바꾸고 싶을 경우 url을 관리하고 있는 urls.py에서 수정하면 되는 것이다.!
url의 이름공간 정하기?
hello_django 프로젝트에 mydjango 앱 하나가 구현되어 있다.
하지만 프로젝트 하나에 여러개의 앱을 만들 수 있는데, 이 때 url이 중복되는 경우가 있을 수 있다.
그래서 url에서 어느 앱의 url을 가리키는 것인지 명확히 표시해줄 필요가 있다.
app_name='mydjango'라고 명시해주는 것이다.
from django.urls import path
from . import views
app_name='mydjango'
urlpatterns = [
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'),
]
이는 template에서도 url사용시 지정해줄 수 있다.
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'mydjango:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
이번에는 template를 이용해 HTML form 요소를 포함시켜본다.
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'mydjango:vote' question.id %}" method="post">
{% csrf_token %}
{% 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 %}
<input type="submit" value="Vote">
</form>
HTML 태그공부
<strong></strong> : 태그 안의 내용을 강조할 때 사용한다. 일반적으로 브라우저는 bold체로 표시한다고 한다.
<form></form> : 사용자가 입력한 데이터를 서버에 전송해준다.
위에서 사용된 form은 사용자의 radio button choice를 전송해주는 것 같다.
url은 이미 연결되어있다.
mydjango/urls.py의 일부 :
path('<int:question_id>/vote/', views.vote, name='vote'),
view를 좀 수정해주어야 한다.
mydjango/views.py
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,)))
# return HttpResponse("You're voting on question %s." % question_id)
import 몇개 해주고, vote함수를 수정해준다.
그리고 브라우저에서 url을 입력하고 난 후 결과
왜 radio button이 나타나지 않는가?
vote를 눌러도 니가 선택을 안했다고 나온다.
선택할게 없으니까 그렇지;;
되돌아가서 어디서 잘못된건지 찾아보았다.
python shell에서 choice 추가하는 부분이 있었는데 그걸 안했더라.
추가하고 나온 화면. 라디오버튼을 붙인 choice 세개가 나오고 vote 버튼이 나온다.
vote 버튼을 누르면 vote의 결과가 나온다.
'개발Study > web' 카테고리의 다른 글
powerMockup (0) | 2020.12.03 |
---|---|
Django와 bootstrap (0) | 2020.11.29 |
Django 지름길 (0) | 2020.11.22 |
Django admin 비밀번호 분실했을 때 (0) | 2020.11.15 |
Django view 추가하기 + Template (0) | 2020.10.25 |
댓글