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

参考: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_404
from django.http import Http404
from django.http import HttpResponse, HttpResponseRedirect
from .models import Question
from 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值