개발Study/web

Django template

happy90 2020. 11. 22. 20:10

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의 결과가 나온다.

 

 

 

 

728x90