-
表单模板
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls: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>
- 使用'post'方法提交表单
Whenever you create a form that alters data server-side, use method="post". This tip isn’t specific to Django; it’s just good Web development practice.
- forloop.counter 返回循环中'for'标签已经被执行过几次
- 使用'post'方法提交时,需要添加{% csrf_token %}模板标签
-
表单url
# polls/urls.py
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote')
# views.vote指定视图函数
# name='vote'则用于模板或者reverse()函数反向找到对应的url
-
视图函数
# polls/views.py
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
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,)))
- 在保存了表单提交的数据后,通过HttpResponseRedirect()函数转到指定页面(HttpResponseRedirect()函数只需要一个URL参数)
As the Python comment above points out, you should always return an HttpResponseRedirect after successfully dealing with POST data. This tip isn’t specific to Django; it’s just good Web development practice.
- 使用reverse()函数可以避免URL的硬编码。
reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
# 其中viewname参数的格式同模板中{% url %}使用的格式相同
-
展示结果
# polls/views.py
from django.shortcuts import get_object_or_404, render
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
# polls/urls.py
url(r'^(?P<question_id>[0-4]+)/results/$, views.results, name='results')
<!--polls/templates/polls/results.html-->
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id %}">Vote again?</a>