“全能”选手—Django 1.10文档中文版Part2

花行 138x68cm 2017年(上海私人馆藏)

迎接大家看我之私房网站《刘江的博客和课程》:www.liujiangblog.com


第一分享Python 及Django教程以及有关的博客


率先片段传送门

其三组成部分传递门

季部分传送门

3.2 模型与数据库Models and
databases

3.2.2 查询操作making
queries

3.3.8
会话sessions

=====

目录

2.5 第一单Django app,Part 3:视图和模板

  • 2.5.1 概览
  • 2.5.2 编写更多的视图
  • 2.5.3 编写能实际干点活的视图
  • 2.5.4 404错误
  • 2.5.5 使用模板系统
  • 2.5.6 删除模板被硬编码的URLs
  • 2.5.7 URL names的命名空间

2.6 第一只DJango app,Part 4:表单和泛型视图

  • 2.6.1 编写一个大概的form
  • 2.6.2 使用泛型视图:减少代码冗余

一 声 珍 重

美术馆的展由十月八日打开历时三月,十月之烈日早让暂缓的朔风取代,数码时代不由得洞中一日世上千年的气——三独月我除了画展,不停止息的写字画画,制定新一年美术馆与碑学研究院的办事计划,往来于美国华夏,去矣中东、北非、西非,一箭河缓缓对正值灵岩山,直布罗陀把西班牙跟摩洛哥挤在拥在——到底天下老大至我们无可知臆测,而在长天之下,想想生命本身,想想办法及文化现象,一个口好以自之怀抱里扎实地触摸任何一个怡然自得的范式,挑战固定的思方式以及不合理极限,是福的。

一个私立美术馆
,不用政府补助就该乘真正对章程尝试的独占和学的坚守——看到一件件深受收藏的著作,还是能记当时之喘息,一如本人所谓的卖画就比如嫁女儿,一个吓婆家才是心安理得的结果,同样,一个审美上出莫大的藏家,在美学上可以交流对的藏家,一定是写及画家之福祉。

大胆走方图 35x35cm 2017年(吉林私人收藏)

《达摩面壁》和《英雄走方》是小品界的创作,都当美国落成,前者有仅的美性向往,直觉而省,藏家是率先差收藏艺术品,我哉该眼光吃惊,后者是高段,同济大学高材生,人物、山水、书法,林林总总收藏了众多件,最高兴的是
,我们一致杯淡酒可以就哲学范畴的悖论、美学的流平衡及力学结构的某些理论原点看到那个一致的结果,这样的艺术家与收藏家就定升华了买卖的涉;最思念取的凡《丽人行》,这同件唐风猎猎的著作是本身以美国画室中针对黄宾虹先生之钻研几乎顶了瓶颈,用宿墨,中锋,净水和赭石在安徽净皮上追溯苍润华滋的美学音韵时,的确,我难以置信这样的结果以斯时空中的意义和价值。毕竟,黄宾虹是同等段落逝去的国画美学神话,我本着学子凛然起敬,但新的美学符号的立,才是艺术家的天职以及任务,正好旧金山亚洲博物馆展《中国汉唐艺术大展》,大唐的老三花团锦簇让自身若面临强喝,重新回眸伟大之古华夏。

直达摩面壁 35x35cm 2017年(苏州私人藏)

唐俑,一个个富丽多情的谜目巧笑倩兮足有丝绸之路习习微风中的轻薄多情,色彩由易经的原理中派生了三生万物的巡回,我定格,摄取美学精神中高贵之曲调,去握别“未成曲调先有内容”的缠绵,挥去长亭外古道边的秋波苍茫——把人间烟火的欢声笑语刻录,《丽人行》把个体的法门生推向一个新的等级。

从未惯性的笔墨,色彩是一个人命之节拍,我在三千已故水吃获取该同样瓢。自顾自饮。

《丽人行》展出之后,有濒临十各项观众以及藏家表达收藏之希望,我又思念这么的创作那效用不仅仅是更换面包钱,它装有为应有有着更胜、更宽的动感意义与价值。

日前
,上海的投资局电话拿下《丽人行》,作为永恒收藏,不发售。老总科学家出生,学术态度谨慎而美学修养深厚,来拘禁了《丽人行》三涂鸦,彼此在微信上多次到了手,为《丽人行》找到这样的泰,是自之福气,而我,一个景间游走的高僧,一个也方式研磨了大半生的画家,对种种结果只有会挥一挥衣袖不携带一样切片云彩,且受我挺立阳光灿烂的五洲上为《丽人行》道一样名声珍重,我拿更前实施。

孟昌明 2018年元月 于姑苏一箭河

僖公牛 68x138cm 2017年

五彩荷 34x138cm 2017年

身写生 68x138cm 2017年

五德 50x70cm 2017年

山水 34x137cm 2017年(吉林私人珍藏)

这山望着那山高 68x138cm 2017年

君子不器 138x34cm 2017年

丽人行 34x137cm 2017年

肖牛者 34x138cm 2017年

与世隔绝之八大 34x34cm 2017年

净瓶 34x34 2017年

铜壶煮三江 34x34cm 2017年

夜半的吸引 138x68cm 2017年

2.5 第一独Django app,Part 3:视图和模板

本章承上启下,主要介绍Django的视图概念。

2.5.1 概览

一个视图就是一个网页“类型”,通常提供一定的效用还是特定的沙盘。例如:在一个博客应用被,你可能会见看到下列视图:

  • 博客主页:显示最新公布之一对情节
  • 条目详细页面:每个条目对应的世代页面
  • 依据年之文章页面:显示指定年内的具备博客文章
  • 冲月之稿子页面:显示指定月内的有所博客文章
  • 基于天的稿子页面:显示指定日内的有博客文章
  • 披露评论:处理对某篇博客发布之褒贬

以我们的投票应用中,我们拿建立下面的视图:

  • 问卷“index”页:显示最新的一对问卷
  • 问卷“detail”页面:显示一个问卷的详细文本内容,没有调查结果但是有一个投票或考察表单。
  • 问卷“results”页面:显示有问卷的投票或调查结果。
  • 投票动作页面:处理对有问卷的某个选项之投票动作。

当Django中,网页和另外的有的情都是通过视图来散发的。视图呈现呢一个简练的Python函数(在依据类的视图中称方法)。Django通过比请求的URL地址来选择相应的视图。

每当你平常之网页上,你或许时时会赶上类似“ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B”的url。庆幸的凡Django支持采取更加简介的URL模式,而非欲编制上面那种复杂的url。

一个URL模式其实就算是一个URL通用表达式,例如:/newsarchive///。为了让URL模式映射到相应的视图,DJango使用URLconfs来完成就同一做事。本学科介绍中心的URLconfs使用办法,更多的始末,请参考6.23节。

2.5.2 编写更多之视图

脚,让咱们开辟polls/views.py文件,输入下列代码:

polls/views.py

def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id)def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id)def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id)

然后,在polls/urls.py文件被参加下面的url模式,将该映射到我们地方新增的视图。

polls/urls.py

from django.conf.urls import urlfrom . import viewsurlpatterns = [ # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),]

现去浏览器被做客“/polls/34/”(注意:这里大概了域名。另外,使用了二级路由,url中都设补偿加polls部分,参考前的章),它将运行detail()方法,然后在页面被展示你当url里供的ID。访问“/polls/34/results/”和“/polls/34/vote/”,将分别显示预定义的地下结果跟投票页面。

上面访问的路由过程如下:当有人看“/polls/34/”地址时,Django将首先加载mysite.urls模块,因为其是settings文件里装的根URL配置文件。在该文件里,Django发现了urlpatterns变量,于是以其外以梯次的展开匹配。当它相当上了^polls/,就解除去url中匹配的公文polls/,然后用剩余的文书“34/”,传递让“polls.urls”进行下一致步的拍卖。在polls.urls,又相当到了r’^(?P<question_id>[0-9]+)/$’,最终结出就是是调整用该模式对应之detail()视图,也就是脚的函数:

detail(request=<HttpRequest object>, question_id='34')

函数中的question_id=’34’参数,是由(?P[0-9]+)而来。在正则表达式中通过一个双圆括哀号,Django会捕获其相当到的值并传递给相应之视图,作为视图的职务参数有,而?P则表示自己要让这个捕获的价指定一个异样的变量名,在视图中可通过question_id这个变量叫作自由的援它,形成一个根本字参数,不用考虑参数的职位。至于[0-9]+则是一个深简单的原生正则表达式,用于匹配同多元连续的数字,它相当到之价值吗就是现实性要传送的参数值。

富有的URL模式还是正则表达式,Django不限制而以url模式中的开方式。但是,你实在没必要书写一个之类的较为愚蠢的蕴藏".html"的模式,它肯定是不曾必要,不够精炼之:

url(r'^polls/latest\.html$', views.index),

卿完全可以据此脚的模式代表上面的:

url(r'^polls/latest$', views.index),

2.5.3 编写能实际干点活的视图

前方我们说了,每个视图至少做简单起事某:返回一个饱含呼吁页面的HttpResponse对象要弹来一个类似Http404的不胜。其它的虽按照你便,你容易关系嘛干嘛。

卿的视图可以自数据库读取记录,或者未读。你可以使Django提供的沙盘系统或第三着的Python模板系统,或者索性啥呢不用。你得生成PDF文件、输出XML,创建ZIP压缩文件,任何你想做的从业,使用任意而想就此底Python库。

倘若Django想要之只有HttpResponse或者一个不行。

坐如此充分方便,接下让我们以DJango自己的数据库API,我们于上头的教程里介绍了之。下面是一个新的index()视图,它会基于通告日期显示最近之5个投票问卷,通过逗号分隔。

polls/views.py

from django.http import HttpResponsefrom .models import Questiondef index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] output = ', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output)# 下面是那些没改动过的视图(detail, results, vote)

但是此间还有只问题:在视图中之页面时硬编码的。如果你想更改页面的示,就务须修改这里的Python代码。因此,让咱来采取Django提供的模版系统,解耦视图和模板之间的联络。

先是,在polls目录下创造一个新的templates目录,Django会在她里面找模板文件。

此间解释一下:Django项目的settings配置文件被定义了怎么加载与渲染模板。默认的安
是DjangoTemplates后端,并且APP_DIRS参数为安装为True。作为老,Django也会见找每个在INSTALLED_APPS配置项里注册过的app本身目录下之templates子目录。

返你才创建的templates目录中,再创一个初的子目录名叫polls,进入该子目录,创建一个初的html文件index.html。换句话说,你的沙盘文件应当是polls/templates/polls/index.html。根据上面的讲,你本得以于DJango中直接采用polls/index.html引用该文件了。

模板命名空间:你也许会想,为什么不把模板文件直接放在polls/templates目录下,而是费劲的再建个子目录polls呢?设想这么个情况,有另外一个app,它也有一个名叫index.html的文件,当Django在搜索模板时,有可能就找到它,然后退出搜索,这就命中了错误的目标,不是我们想要的结果。解决这个问题的最好办法就是在templates目录下再建立一个与app同名的子目录,将自己所属的模板都放到里面,从而达到独立命名空间的作用,不会再出现引用错误。

今天,将下列代码写副文件:
polls/templates/polls/index.html

{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul>{% else %} <p>No polls are available.</p>{% endif %}

还要,修改视图文件,让初的index.html文件生效:
polls/views.py

from django.http import HttpResponsefrom django.template import loaderfrom .models import Questiondef index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))

上面的代码会加载polls?index.html文件,并传递让它一个参数,这个参数是一个字典,包含了模版变量名和python对象中的照耀关系。

每当浏览器中经走访“/polls/”,你得望一个列表,包含“What’s
up”的问卷,以及连接至那针对性诺详细内容页面的链接点。

快捷方式:render()

每当事实上使用中,加载模板、传递参数,返回HttpResponse对象是身更常用但的操作了,为了省力气,Django提供了一个快捷方式:render函数,一步到位!看如下代码:

polls/views.py

from django.shortcuts import renderfrom .models import Questiondef index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)

render()函数的率先单职位参数是要对象(就是view函数的首先独参数),第二个职务参数是模板,还可产生一个可选的老三参数---一个字典,包含需要传递给模板的数码。最后render函数返回一个透过字典数据渲染了之模版封装而成的HttpResponse对象。

2.5.4 404错误

兹受咱来编排返回具体问卷文本内容的视图:

polls/views.py

from django.http import Http404from django.shortcuts import renderfrom .models import Question# ...def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("Question does not exist") return render(request, 'polls/detail.html', {'question': question})

这边产生只新定义:如果请的问卷ID不有,那么会弹有一个Http404荒唐。

稍后咱们会谈谈你该当polls/detail.html里面写点啊代码,但是今公可简简单单的先写这么个东西,用来展示地方的404荒唐:

polls/templates/polls/detail.html

{{ question }}

快捷方式:get_object_or_404()

虽如render函数一样,Django同样为公提供了一个偷懒的不二法门,替代点的多行代码,那即便是get_object_or_404()方法,参考下面的代码:

polls/views.py

from django.shortcuts import get_object_or_404, renderfrom .models import Question# ...def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})

变更说自从未提醒您,和render一样,也急需在Django内置的快捷方式模块中导入get_object_or_404()!

get_object_or_404()函数将一个Django模型作为第一独岗位参数,后面可以跟达到自由个数的重中之重字参数(python函数参数的分类及语法一定要作懂了!这些重大字参数是传递给范管理器的get()函数的,在末端会摆到。),如果目标非有则弹出Http404破绽百出。

理念:为什么要费劲的使用一个get_object_or_404()快捷方式,而不是让系统自动的捕获ObjectDoesNotExist异常或者弹出模型API的Http404异常?仅仅只是为了少写点代码?因为后两者会耦合模型层和视图层。Django的一个非常重要的设计目标是维持各层级之间的松耦合。更多的内容请参考3.3.5节。

相同,这里还有一个get_list_or_404()函数,和上面的get_object_or_404()类似,只不过是故来取代filter()函数,当查问列表为空时弹出404破绽百出。(filter是范API中因故来过滤查询结果的函数,它的结果是一个列表集。而get则是询问一个结出的道,和filter是一个同多个底分别!)

2.5.5 使用模板系统

返detail()视图。将上下文变量question传递让相应的html模板,它看起如下所示:

polls/templates/polls/detail.html

<h1>{{ question.question_text }}</h1><ul>{% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li>{% endfor %}</ul>

眼前我们说了了,在模板系统遭到圆点“.”是全能的魔术师,你得就此它访问对象的属性。在例子{{
question.question_text
}}中,DJango首先会在question对象被尝试摸一个字典,如果失败,则尝试摸属性,如果还失败,则尝试当列表的目进行查询。

每当 {% for %}
循环中的法门调用——poll.choice_set.all其实就是Python的代码poll.choice_set.all(),它以回到一组而迭代的
Choice 对象,并因此在 {% for %} 标签中。

更多内容要查看3.5节省之模版向导!

2.5.6 删除模板被硬编码的URLs

当polls/index.html文件中,还有一部分硬编码存在,也就是herf里之“/polls/”部分:

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

内的紧耦合对于代码修改十分不利于。
但是,我们面前为urls定义了一个name别名,可以据此她来代替。具体代码如下:

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

Django会在polls.urls文件被觅name='detail'的url,具体的即是下面这行:

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

举个栗子,如果你想将polls的detail视图的URL更换为polls/specifics/12/,那么您免需以模板被还修改url地址了,仅仅只是待以polls/urls.py文件被,将相应之正则表达式改化下面这样的便尽了:

# 添加新的单词'specifics'url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),

2.5.7 URL names的命名空间

准课程例子中,只发1单app也就算是polls,但是于切实可行中酷显然会生5个、10单、更多的app同时设有一个类面临。Django是哪些区分这些app之间的URL
name呢?

答案是运用URLconf的命名空间。在polls/urls.py文件之启幕部分,添加一个app_name的变量来指定该使用的命名空间:

polls/urls.py

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

今日,让咱们以代码修改得更严谨一点,将下面的:
polls/templates/polls/index.html

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

修改为:

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

专注引用方法是引号而不是圆点也无是斜杠!!!!!!!!!!!!

顶之,我们可入下部分的学科了。

2.6 第一单DJango app,Part 4:表单和泛型视图

以有着重介绍form表单相关。

2.6.1 编写一个简单的form

当今于咱们原先底polls/detail.html文件被上加一个表单元素:

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>

概括说明:

  • 方的沙盘显示平系列单选按钮,按钮的价值是挑选之ID,按钮的名是字符串"choice"。这象征,当你选了中间有按钮,并付诸表单,一个包含数据choice=#的POST请求将受发送哲学至指定的url,#举凡叫选择的挑三拣四之ID。这即是HTML表单的基本概念。
  • 比方你来自然之前端开发基础,那么form标签的action属性和method属性你当非常了解其的意义,action表示若要是发送的目的url,method表示提交数据的方,一般分POST和GET,更多的分解就是非是本教程干的事务了,你要补课。
  • forloop.counter是DJango模板系统管理专门提供的一个变量,用来代表你时轮回的次数,一般用来给循环型增长有序数标。
  • 鉴于我们发送了一个POST请求,就得考虑一个跨站请求伪造的题材,简称CSRF(具体意思请百度)。Django为而提供了一个简易的艺术来避免这麻烦,那便是于form表单内上加相同漫长{%
    csrf_token
    %}标签,标签名不可更改,固定格式,位置任意,只要是在form表单内。但是(译者注),这个方式对form表单的付出方式方便好使,但是一旦是故ajax的措施交给数据,那么即使非常棘手了。个人觉得未若直接以Django配置中关闭是仿佛发生图,其实然并卵的CSRF得矣。

今天,让咱创建一个处理提交过来的数据的视图。前面我们已写了一个“占坑”的vote视图的url:
polls/urls.py

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

以及“占坑”的vote视图函数,我们将坑填起来:
polls/views.py

from django.shortcuts import get_object_or_404, renderfrom django.http import HttpResponseRedirect, HttpResponsefrom django.urls import reversefrom .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): # 发生choice未找到异常时,重新返回表单页面,并给出提示信息 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.POST是一个接近字典的靶子,允许而通过键名访问提交的数额。本例中,request.POST[’choice’]返给挑选项的ID,并且值的档次永远是string字符串,那恐惧它看起像数字,记住了!!!!同样的,你呢得以为此接近的招取得GET请求发送过来的数量,一个道理。
  • request.POST[’choice’]起或接触一个KeyError异常,如果您的POST数据里无提供choice键值,在这种气象下,上面的代码会回到表单页面并叫起左提示。译者注:通常我们会为个默认值,防止这种好的起,例如:request.POST[’choice’,None],一个None解决有题目。
  • 每当选取计数器加一晚,返回的是一个HttpResponseRedirect而非是先前咱们常常因此之HttpResponse。HttpResponseRedirect需要一个参数:重定向的URL。这里来一个建议,当您成拍卖POST数据后,应当保持一个好好的惯,始终返回一个HttpResponseRedirect。这不仅是本着Django而言,它是一个两全其美的WEB开发习惯。
  • 咱以面HttpResponseRedirect的构造器中利用了一个reverse()函数。它会辅助我们避免以视图函数中硬编码URL。它首先需一个我们于URLconf中指定的name,然后是传递的数码。例如'/polls/3/results/',其中的3凡是某question.id的价。重定向后拿上'polls:results'对应之视图,并拿question.id传递让它。白话来讲,就是管活扔给另外一个路由对应之视图去干。

当有人对某问题投票后,vote()视图重定向到了问卷的结果显示页面。下面我们来形容是处理结果页面的视图:
polls/views.py

from django.shortcuts import get_object_or_404, renderdef results(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/results.html', {'question': question})

一律,还待写个模板。(译者注:路由、视图、模板、模型!你需要的套路....)

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>

今昔若可博得浏览器被访问/polls/1/了,投票吧。你会看到一个结出页面,每投同不行,它的内容即创新一糟糕。如果你提交的时节没有选项目,则会获一个谬误提示。

注释:(怎么这么多注释....)在上面的vote视图中的代码存在一点小问题。如果有2个用户同时在对某项进行提交时,很有可能发生同时对数据库进行读写的情况,它有可能导致数据的不协调,也就是所谓的“竞态”,如果你感兴趣,可以参考6.15节相关的通过使用F()查询来避免竞态的讨论和介绍。

2.6.2 使用泛型视图:减少代码冗余

点的detail、index和results视图的代码非常相像,有硌冗余,这是一个顺序猿不克经得住的。他们还有着类似之事情逻辑,实现类似的意义:通过打URL传递过来的参数去数据库查询数据,加载一个模板,利用刚才底多寡渲染模板,返回这个模板。由于此进程是这么之普遍,Django又特别善解人意的帮助您想艺术偷懒了,它提供了一如既往种植快捷方式,名也“泛型视图”系统。

今日,让我们来试看用原来的代码改吧利用泛型视图的点子,整个过程分三步走:

  • 改变URLconf
  • 除去一些初的无用的视图
  • 行使基于泛型视图的新视图

注释:Django官方的“辩解”
干什么以学科的代码来回改动这么累?
报:通常在描写一个Django的app时,我们同样开始就要控制是利用泛型视图还是不要,而不是相等及代码写及一半了才重构你的代码成泛型视图。但是仍学科为了让您清晰的知情视图的内蕴,“故意”走了同一长达比较2之路,因为咱们的哲学是:在你使用计算器之前您得先清楚基本的数学公式。

修改URLconf

开辟polls/urls.py文件,将其修改成下面的楷模:

from django.conf.urls import urlfrom . import viewsapp_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'),]

要小心:在上头的底第2,3条文中将原本的<question_id>改成了<pk>.

修改视图

连接下去,打开polls/views.py文件,删掉index、detail和results视图,替换成Django的泛型视图,如下所示:

polls/views.py

from django.shortcuts import get_object_or_404, renderfrom django.http import HttpResponseRedirectfrom django.urls import reversefrom django.views import genericfrom .models import Choice, Questionclass IndexView(generic.ListView): template_name = 'polls/index.html' context_object_name = 'latest_question_list' def get_queryset(self): """返回最近发布的5个问卷.""" 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):... # 这个视图未改变!!!

当这里,我们使用了少数种泛型视图:ListView和DetailView(译者注:它们是作为父类被连续的)。这两边分别代表“显示一个对象的列表”和“显示特定项目对象的详细页面”的抽象概念。

  • 各个一样种泛型视图都要掌握它如果作用在谁模型上,这通过model属性提供。

  • DetailView泛型视图需要由URL捕获到的号称"pk"的主键值,因此我们当url文件中将2和3漫长目的<question_id>修改成了<pk>

默认情况下,DetailView泛型视图使用一个叫<app name>/<model name>_detail.html的模版。在本例中,实际应用的是"polls/question_detail.html"。template_name属性就是用来指定这个模板名之,用于代替自动生成的默认模板名。(译者注:一定要是仔细考察地方的代码,对号落座,注意细节。)同样的,在resutls列表视图中,为了指定template_name为'polls/results.html',这样虽保险了虽然resulst视图和detail视图同样继承了DetailView类,使用了同等的model:Qeustion,但它们仍会来得不同之页面。(译者注:模板不同嘛!so
easy!)

类似之,ListView泛型视图使用一个默认模板称为<app name>/<model name>_list.html。我们为利用template_name这个变量来报ListView使用我们既在的
"polls/index.html"模板,而未是使它们自己默认的可怜。

于科目的面前有,我们于模板提供了一个暗含question和latest_question_list的上下文变量。而对于DetailView,question变量会叫电动提供,因为咱们采用了Django的型(Question),Django会智能的精选适合的上下文变量。然而,对于ListView,自动生成的上下文变量是question_list。为了掩盖其,我们提供了context_object_name属性,指定说咱们期望以latest_question_list而不是question_list。

现今公得运行开发服务器,然后试试基于泛型视图的应用程序了。
查看更多关于泛型视图的内容,请往3.6节。

顶这边,本节的始末了了,你可以起产一样稍微节之上学。
道博主翻译的尚足以纵点赞支持一下吧!

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。