继续part3的部分。我们继续学习poll应用程序,并且会专注于简单的表单和简化我们的代码。
编写一个简单的表单
让我们更新一下poll应用的detail模板(polls/detail.html),为了让加入HTML的<form>元素:
image.png
一个快速预览:
- 上面的模板为每个question的选择使用了一组radio button(单选按钮)。每个radio button的值会关联到question的id上。每个radio button的name都是“choise”。这意味着,当用户选择了radio button并提交表单时,它会发送一个POST数据choise=#,#是选择的radio button的id。这是HTML表单的基础概念。
- 我们给表单的action设置为{% url 'polls:vote' question.id %},并且我们设置method=“post”。使用method=“post”(与method=“get”相反)很重要,因为表单的提交会修改服务端的数据。当你使用表单来修改服务端的数据时,使用method="post"。这个提示不仅仅是针对django,它是优秀web开发人员习惯。
- forloop.counter指出,for循环标签执行了多少次循环。
- 自从我们创建一个POST表单后(可以修改数据),我们需要关注跨域请求伪造(Cross Site Request Forgeries)。幸亏,你不用担心这有多难,django提供了非常好用的系统来解决这个问题。简言之,所有的POST表单应该使用{% csrf_token %}标记为内部URL。
现在,让我们创建django视图来处理提交的数据,并对它做点什么吧。请记住,教程3中,我们给polls应用创建的URLconf包含了这一行:
image.png
我们还有一个暂未使用的vote()函数。让我们创建一个真实的描述,把下面的代码加入到polls/views.py中:
image.png
这些代码提及了一些教程到目前为止没有涉及的东西:
- request.POST是一个类似于字典的对象,让你可以通过key来提交数据。这样的话,request.POST['choise']以字符串的形式返回被选择的ID。request.POST值总是字符串。
要注意django提供的request.GET来访问get数据是同样的方法,但是我们明确在代码中使用request.POST,来确保数据只能通过POST来更改。 - request.POST['choise']将会在choise没有提供POST数据时抛出KeyError异常。上面的代码检查
KeyError
,并且如果choise没有给出的话,会重新展示带有错误信息的question表单。 - 在增加了choise的数量之后,代码返回一个HttpResponseRedirect而不是正常的HttpResponse。HttpResponseRedirect只有一个参数:用户要跳转的URL(这种情况,请看下面我们是如何构建URL的)。
像python注释一样指出,在成功处理POST数据后,你应该总是返回一个HttpResponseRedirect对象。这提示不仅仅适用与django,也是一个优秀的web开发人员的习惯。 -
这个例子中,我们在HttpResponseRedirect对象的构造函数中使用reverse()函数。这个函数避免了我们在视图函数的URL中使用硬编码。它会给定视图一个名字,我们通过控制URL的可变部分来指向视图。既然这样,我们使用在教程3中使用的URLconf,reverse()函数返回类似于这样的字符串:
image.png
3是question.id的值。这个重定向的URL会调用“results”来展示最后的页面。
在教程3中提及过,request是一个HttpResponse对象,更多关于HttpResponse对象的内容请看request and response documentation。
当用户投票了一个问题后,vote()函数会重定向结果页面到question页面。让我们来写一下这个视图:
image.png
网友评论