django框架从零开始_008_页面元素 表单处理

来源:互联网 发布:公司软件著作权转让 编辑:程序博客网 时间:2024/06/04 00:52

参考:https://docs.djangoproject.com/en/1.9/intro/tutorial04/


我们现在来练习更多的views相关的表单处理方式。下面来更新一下polls/detail.html页面,如下:

<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%}    <p>    <input type="radio" name="choice" id="choice-{{forloop.counter}}" value="{{choice.id}}" />    <label for="choice-{{forloop.counter}}">{{choice.choice_text}}</lable>    </p>{%endfor%}<p><input type="submit" value="Vote" /></p></form>

我们在这里对question的每个choice捡了一个input radio选单。我们设置了action为{%url 'polls:vote' question.id%},原理同上一节;forloop.counter是for循环的计数器,十分好用;csrf_token是django提供的一个跨站检查的token,使你无需担心跨站伪请求,只需要在form中调用{%crsf_token%}即可。本地站内的表单都推荐使用此方法。

OK,既然是提交到vote页面,那我们先来修改polls/views.py里的vote部分:

from django.shortcuts import render, get_object_or_404from django.http import Http404from django.http import HttpResponse, HttpResponseRedirectfrom .models import Questionfrom django.core.urlresolvers import reverse......def vote(request, question_id):    #return HttpResponse("You're voting on question %s." % 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 did not 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,)))



有很多没学过的东西,我们来看一下:

  • request.POST: 一个保存请求中POST来的信息的dict,里边的信息都默认被保存为字符串。同理还有request.GET。
  • request.POST['choice']会报KeyError如果post信息里不包含choice。代码中检测这个KeyError,并返回显示之前的页面,并带着error_message信息。
  • 如果顺利获取到choice,那么记录这个votes的数量+1,之后返回调用了HttpResponseRedirect方法。这个方法需要一个参数:用户会跳转到的url,一会儿我们会详细说明。顺带提及,正确处理完POST参数后,应该总是会调用HttpResponseRedirect,这是一个良好的网页设计习惯。
  • 我们在HttpResponseRedirect方法中调用了reverse()方法来创建url。这个函数避免了我们写死url地址,而是用了我们urls.py保存的样式,利用一个view名称(包括namespace)和相应参数来创建需要的url。我们在polls/urls.py中定义的是:
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
那么这里我们获得的url就是形如
'/polls/3/results/'
的字串。


关于更多的request的用法,请参考 https://docs.djangoproject.com/en/1.9/ref/request-response/  (HttpRequest对象)


下面来修改原来的detail view:

def results(request, question_id):    # response = "You're looking at the results of question %s."    # return HttpResponse(response % question_id)    question = get_object_or_404(Question, pk=question_id)    return render(request, 'polls/results.html', {'question':question})


之后新建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>


大功告成,我们来尝试一下:

首先打开Question首页:


点击question,进入


已经可以点选投票了,点击”not much"选框,点击vote之后:


OK,投票结果已经记录了。可以点击vote again返回再投,可以看到result界面中的计数在增长。


返回投票页面,如果不选择直接提交,应该会走到我们的错误处理流程中:


唉唉?好像哪里不对。仔细一看发现原来是在views.py中忘了import Choice。赶紧填上,再次运行:


完毕。

0 0
原创粉丝点击