上一篇已经完成了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. 学习笔记CB014:TensorFlow seq2seq模型步步进阶

    神经网络.<Make Your Own Neural Network>,用非常通俗易懂描述讲解人工神经网络原理用代码实现,试验效果非常好. 循环神经网络和LSTM.Christopher ...

  2. mac下 部分服务启动,结束, 查看状态的命令

    以sshd服务为例 启动sshd服务:sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist 停止sshd服务:sudo laun ...

  3. BInsertSort

    #include <bits/stdc++.h> using namespace std; #define MAXSIZE 200000 typedef int KeyType; type ...

  4. Mac使用

    安装you-get: 用到mac下安装软件的工具:brew 百度搜brew到官网首页照说明在终端执行一段指令 安装方法:命令行输入 /usr/bin/ruby -e "$(curl -fsS ...

  5. 【原创】Bug管理操作规范个人经验总结

    1. 禅道简介 禅道是一个基于“敏捷开发”模式的软件开发全生命周期管理软件,在国内的软件开发公司里占据最大的份额,从大公司到小公司,都能适用. 笔者使用禅道多年,根据自己的经验总结了一套Bug管理的方 ...

  6. [转载]使用QTP测试Windows对象

    Desktop对象的使用: 通过Desktop对象,可以访问Windows的桌面顶层对象.Desktop对象包括CaptureBitmap.ChildObjects.RunAnalog方法. (1)  ...

  7. ASP.NET: Cookie会话丢失,Session超时配置

    问题描述: asp.net应用中web.config的SessionState节点:原先是 <sessionState mode="InProc" timeout=" ...

  8. sql调优2

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据 ...

  9. pip改源

    临时 python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django==1.10 # ==后边指定版本号,也可以不指定 ...

  10. python 函数内使用自己的函数名

    def p(): import sys print sys._getframe(1).f_code.co_name def f(): p() def f1(): p() if __name__ == ...