知识点

  1) 表单的编写

    CSRF问题

    forloop.counter

  2) 视图函数的知识

    GET和POST

    HttpResponseRedirect的使用

    reverse的使用

  3) 通用视图

    CBV(class_base view)

    CVB在URLs的配置, 使用as_view()

    ListView和DetailView

    注意主键获取, 名字用fk

    默认模板的问题

    自带变量问题

1 编写表单

  polls/templates/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 %}
<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>

  表单中的第一个input, type为radio表示单选框, name为choice表示提交的时候该input的value会提交成 choice=值 的形式

  form的属性添加了action表示提交地址, method设置为post非常适合用于表单提交数据

  forloop.counter表示for循环的次数, 类似于我们常用的i

  由于提交的表单会修改数据, 这有可能造成CSRF(Cross Site Request Forgeries, 跨站点请求伪造)

  为了防范这类问题, 针对修改内部网站的所有PSOT表达都应该加上{% csrf_token %}

  URLs配置如下

  polls/urls.py

url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),

  视图函数编写为

  polls/views.py

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse from .models import Choice, Question
# ...
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):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

  request可以得到GET和POST两个值, 得到的结果是以个类似于字典的值, 可以用 request.GET['名字'] 或者 request.POST['名字'] 的方式来获取值

  返回使用的是HttpResponseRedirect 而不是常用的HttpResponse, 其只需传入一个参数, 是用于重定向的地址, 类型是字符串

  一般POST成功处理之后都应该使用HttpResponseRedirect, 原因是HttpResponseRedirect可以防止用户在点击回退按钮的时候重复提交表单

  可以使用reverse函数来避免硬编码(hardcode )的URL, reverse()函数可以传入两个参数, 一个是视图名, 一个是URL的参数

    如果question_id为3 那么返回的URL为

'/polls/3/results/'

  现在编写results的视图

  polls/views.py

from django.shortcuts import get_object_or_404, render

def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})

  再创建results的模板

  polls/templates/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>

  注意:

    此次的投票系统可能出现一些小BUG

    两个使用者可能在同一时刻提交同一个选项, 该选项的计数可能不正确

    可以参见此来解决问题

2 编写通用视图

  通过编写通用的视图, 可以复用代码, 进而减少代码量

  对于通用视图, Django提供了一个快捷方式, 叫做 通用视图系统( "generic views" system)  

  具体步骤为

    1) 转换URLconf

    2) 删除一些旧的,不需要的视图

    3) 根据Django的通用视图编写新视图

  修改URL配置
  polls/urls.py

from django.conf.urls import url
from polls import views app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', 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'),
]

    - 注意第二个第三个URL的名字改为了pk

  修改视图

  polls/views.py

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from .models import Choice, Question class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by('-pub_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):
# 不做修改

  在这当中用到了ListViewDetailView两个通用视图, 分别用于显示

    对象列表

    特定对象的详细信息

  注意两点

    1) 必须要设置model, 要为其指定一个表(这里需要用类)

    2) 在捕获URL的时候, 需要获得主键信息, 这个时候就需要把正则表达式分组命名为pk, 这样命名Django才能正常识别

  默认情况下, DetailView返回的模板名也是有格式的(ListView同理), 格式为

<app name>/<model name>_detail.html
<app name>/<model name>_list.html

  另外还需要说明的是, 默认会提供一个上下文变量question 和一个全局变量latest_question_list

  对于DetailView, 使用模型Question会自动提供变量question

  对于ListView, 使用模型Question会自动提供变量question_list

  如果要重写这个变量, 可以通过context_object_name属性来完成, index()函数就修改成了last_question_list

context_object_name = 'latest_question_list'

  如果需要更多内容, 可以点击了解更多的通用视图

  

07 - Django应用第四步的更多相关文章

  1. JAVA EE企业级开发四步走完全攻略 [转]

    http://bbs.51cto.com/thread-550558-1.html 本文是J2EE企业级开发四步走完全攻略索引,因内容比较广泛,涉及整个JAVA EE开发相关知识,这是一个长期的计划, ...

  2. 07: Django 使用ldap登录、注销等

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  3. TCP四步挥手的各种状态转换图

    对于TCP四步挥手时的各种状态转换,网上有很多资料.但是有很多描述不是很容易理解,甚至是描述错误,不如这篇文章里http://www.cnblogs.com/Jessy/p/3535612.html# ...

  4. ElasticSearch第四步-查询详解

    ElasticSearch系列学习 ElasticSearch第一步-环境配置 ElasticSearch第二步-CRUD之Sense ElasticSearch第三步-中文分词 ElasticSea ...

  5. 四步让你的网站秒开,wordpress框架为例子,其他框架道理类似

    我这里以wordpress框架制作的网站为例子,效果可以看看我的网站,香港的垃圾主机199一年2M带宽,速度也能秒开,不信试试效果33小游戏 我的是wordpress制作的网站,大家都知道WP各种臃肿 ...

  6. 四步完成NodeJS安装,配置和测试

    四步完成NodeJS安装,配置和测试 NodeJS 官网地址: http://nodejs.org/ 第一步:在官网点击 ’ INSTALL ’,下载相应的版本(我的机器是Win7专业版 64bit) ...

  7. Ajax发送异步请求(四步操作)

    1.第一步(得到XMLHttpRequest) *ajax其实只需要学习一个对象:XMLHttpRequest,如果掌握了它,就掌握了ajax!! *得到XMLHttpRequest >大多数浏 ...

  8. 用PHPcms V9四步完成WAP手机站搭建

    用PHPCMS最新发布的V9搭建了ONOW中文网,WEB网站(www.onow.cn)完成后,有用户提供手机访问的问题, 于是着手搭建ONOW手机WAP站(3g.onow.cn). 用PHPCMS V ...

  9. 文件下载(只需要简单的四步),Java中都通用

    我们就直接切入主题啦,文件下载只需要四步: 1.设置文件ContentType类型 2.设置文件头 3.通过response获取ServletOutputStream对象(out) 4.写到输出流(o ...

随机推荐

  1. Swift_4_闭包(Blocks)

    import Foundation println("Hello, World!") var arr = [1,2,4,6,74,2] func hasClosure(list:[ ...

  2. C++中面向对象的理解

     1.对于OO(面向对象)的含义,并非每一个人的看法都是同样的. 即使在如今.假设问十个人,可能会得到15种不同的答案.差点儿全部的人都会允许继承和多态是OO中的概念.大多数人还会再加上封装. 另 ...

  3. HDU 2588 GCD &amp;&amp; GCD问题总结

    GCD(一) 题目: The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written ( ...

  4. 反射机制,jvm,class类型

    [说明]这是上午完成的内容或者说是接触到的知识点,包括servlet简单的数据库连接,表格的显示需要用到的插件jstl,还有最最多的java反射原理的讲解 1)数据库的设计 2)编程中用到的知识点 3 ...

  5. 【BZOJ2337】[HNOI2011]XOR和路径 期望DP+高斯消元

    [BZOJ2337][HNOI2011]XOR和路径 Description 题解:异或的期望不好搞?我们考虑按位拆分一下. 我们设f[i]表示到达i后,还要走过的路径在当前位上的异或值得期望是多少( ...

  6. 九度OJ 1249:次小生成树 (次小生成树)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:203 解决:56 题目描述: 最小生成树大家都已经很了解,次小生成树就是图中构成的树的权值和第二小的树,此值也可能等于最小生成树的权值和,你 ...

  7. Django 之 ModelForm 组件

    Django的model form组件 扩展:Django 之Form组件 首先我们要知道 Model 和 Form 分别时干什么的 Model  生成表数据 Form  对表单.字段进行校验 Dja ...

  8. Android系统移植与调试之------->MTK 标准编译命令

    命令格式:./maketek [option] [project] [action] [modules]Option:   -t ,-tee :输出log信息到当前终端   -o , -opt=-- ...

  9. 【转载】解决Apache2+PHP上传文件大小限制的问题

    原文出处:http://evol1216.blog.163.com/blog/static/13019958020106783623528/ 在用PHP进行文件上传的操作中,需要知道怎么控制上传文件大 ...

  10. java基础入门之数组循环初始化

    /* Name:数组循环化 Power by Stuart Date:2015-4-23 */public class ArrayTest02{ public static void main (St ...