上一篇已经完成了polls的基本功能,接下来完善剩下的vote功能和并使用generic views改进请求处理view。包含表单的简单运用和前后台参数传递。

目录

  • vote:完善投票功能
  • generic views:改进views.py

vote

编辑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 %}
<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>
  • 添加了form表单,使用post提交,提交到的地址是polls:vote代表一个地址,比如:http://127.0.0.1:8000/polls/4/vote/.
  • 这里涉及到了表单提交,添加{% csrf_token %}防止csrf攻击,原理就是每次使用的token不一致,导致无法进行伪造请求,从而防止。
  • forloop.counter是for循环的计数器。

编辑views.py添加投票功能,注意引入相关的类

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):
return render(request, 'polls/detail.html', {
'question': question,
'error_message':"you did`t select choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
request.POST['choice']从post请求里面获取前台传递过来的参数,request.POST 是一个dictionary,键是参数名,值是参数值,档案如果是get请求的话就是request.GET
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))在投票成功之后将页面进行了重定向,防止用户使用浏览器的回退功能之后重复提交表单 到现在为止功能已经完成了,可以进行测试了,启动服务器然后测试相关功能

generic views

对于很多web app来说,需要展示内容的方式相近,比如:查看某个列表,查看某一个的具体内容等等,为此Django提供了generic views——Django诠释了什么是快速便捷开发!

使用generic views改写views.py

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseRedirect
from models import Question, Choice
from django.views import generic
from django.core.urlresolvers import reverse # Create your views here.
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' def get_queryset(self):
return Question.objects.order_by('-publ_date')[:5] class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html' class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html' 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):
return render(request, 'polls/detail.html', {
'question': question,
'error_message':"you did`t select choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

我们将index,detail,result都改写了,使用到了ListView和DetailView。

IndexView复写了get_quesryset方法来实现我们自己的逻辑,设置了模板页面和返回的参数名称

DetailView设置了展示详细信息所需要的model和模板页面

既然使用了generic views就需要改写urls.py

from django.conf.urls import url
from . import views app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name = 'index'),
url(r'^(?P<pk>[0-9]+)/detail/$', views.DetailView.as_view(), name = 'detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name = 'results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name = 'vote'),
]

为了使用generic views把参数名称改为pk,因为在DetailView里面已经使用了该名称——这就是约定优于配置。

总结

整个程序基本写完了,我们回过头来发现,我们自己真正写了的代码真不多,基本都是依赖Django完成的。可见使用Django快速建站还是有道理的。


完整代码

http://pan.baidu.com/s/1o8zqGhs

frist Django app — 四、 完善View的更多相关文章

  1. frist Django app — 三、 View

    前面已经说过了Django中model的一些用法,包括orm,以及操作的api,接下来就是搭一些简单的界面学习view——Django中的view.主要介绍以下两个方面: url映射 请求处理 模板文 ...

  2. frist Django app — 五、Test

    Test——很重要但是没有被重视起来的一个环节,至少是我自己,其实自己之前在做java web的时候就去尝试过怎么做REST接口的测试,一直没有找到一种合适方式,而且因为时间紧没有进一步深究,但是造成 ...

  3. frist Django app — 一、 创建工程

    缘起 既然python都学了,学习python的时候感觉是相见恨晚,一种新的编程语言带给我一种新的思考问题的方式,为了巩固学过的东西并进一步学习python,就想学学Django,看看会不会带给我关于 ...

  4. frist Django app — 一、 创建工程(转载)

    转载地址:https://www.cnblogs.com/sunshine-2015/p/5658283.html 缘起 既然python都学了,学习python的时候感觉是相见恨晚,一种新的编程语言 ...

  5. Django App(四) Submit a form

    经过前面的努力,到这里我们已经基本完成了,从服务器到浏览器的数据下发,还没有解决从浏览器到服务器的数据上传,这一节将创建一个Form获取从浏览器提交的数据 1.新建Form 接着前面建的项目,网上调查 ...

  6. frist Django app— 二、 Model和管理界面

    Django是符合MVC架构的,这里现学习M—Model,而且Django自带了一个管理model(数据库)的界面,所以一并学习. Database 配置 编辑Django的配置文件settings. ...

  7. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第四部分(Page 9)

    编写你的第一个 Django app,第四部分(Page 9)转载请注明链接地址 该教程上接前面的第三部分.我们会继续开发 web-poll 应用,并专注于简单的表单处理和简化代码. 写一个简单的表单 ...

  8. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第一部分(Page 6)

    编写你的第一个 Django app,第一部分(Page 6)转载请注明链接地址 Django 2.0.1 官方文档翻译: Django 2.0.1.dev20171223092829 documen ...

  9. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第五部分(Page 10)

    编写你的第一个 Django app,第五部分(Page 10)转载请注明链接地址 我们继续建设我们的 Web-poll 应用,本节我们会为它创建一些自动测试. 介绍自动测试 什么是自动测试 测试是简 ...

随机推荐

  1. GIT & VersionControl

    一.Git Git(读音为/gɪt/.)是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理. [1]  Git 是 Linus Torvalds 为了帮助管理 Linux ...

  2. xamarin android 汉字转拼音

    使用微软的 ChnCharInfo.dll,这个库不仅能在 windows 下完美运行,竟单独在android下也可以完美运行,直接引用即可.当然是使用 visual studio 开发安卓啦,具体用 ...

  3. C# EnumHelper Enum的值,Description,ToString()的相互转换

    首先定义枚举类型,如下: /// <summary> /// 板块 /// </summary> public enum Plate {         [Descriptio ...

  4. ASP.NET MVC中,动态处理页面静态化 【转载】

    首先解释一下什么是动态处理页面静态化 对于需要静态化的页面,第一次访问某个Action时,会先执行Action,并在页面渲染后向Response和服务器中网站的目录下都写入需要返回的html,而第二次 ...

  5. c# 正则表达式取值、替换

    //例如我想把如下格式记录中的NAME值修改为WANG string line = "ADDR=1234;NAME=ZHANG;PHONE=6789"; Regex reg = n ...

  6. c# 程序只能运行一次(多次运行只能打开同一个程序)

    转自:https://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9/2291420309357 ...

  7. 如何清除Windows10中的恢复分区

    在Windows搜索框中键入Cmd.出现结果列表. 右键单击命令提示符并选择以管理员身份运行. 在命令提示符下键入diskpart,然后按Enter键. 输入list disk并按Enter键. 出现 ...

  8. 如何使用linux+xvfb+python+rfs+firefox+jenkins实现UI自动化

    首先说一下背景,在项目中使用windows执行机进行rfs脚本运行时,遇到两个问题: 1.Jenkins的多个slave节点和master的连接通过windows插件去建立,如果出现slave断连,无 ...

  9. JavaScript易混淆的零碎知识点积累

    1.callee属性 和 caller属性. 区别:两者的调用对象不同 arguments.callee:指向拥有这个arguments对象的函数,在递归运算中经常用到. functionName.c ...

  10. vscode setting

    { "files.autoSave": "onFocusChange", "window.openFilesInNewWindow": tr ...