当前位置:K88软件开发文章中心网站服务器框架django → 文章内容

Django 通用视图

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-25 14:19:21

由 lxjazni_7 创建,小路依依 最后一次修改 2016-02-24 这里需要再次回到本书的主题: 在最坏的情况下, Web 开发是一项无聊而且单调的工作。 到目前为止,我们已经介绍了 Django 怎样在模型和模板的层面上减小开发的单调性,但是 Web 开发在视图的层面上,也经历着这种令人厌倦的事情。Django的通用视图 可以减少这些痛苦。 它抽象出一些在视图开发中常用的代码和模式,这样就可以在无需编写大量代码的情况下,快速编写出常用的数据视图。 事实上,前面章节中的几乎所有视图的示例都可以在通用视图的帮助下重写。在第八章简单的向大家介绍了怎样使视图更加的“通用”。 回顾一下,我们会发现一些比较常见的任务,比如显示一系列对象,写一段代码来显示 任何 对象内容。 解决办法就是传递一个额外的参数到URLConf。Django内建通用视图可以实现如下功能:完成常用的简单任务: 重定向到另一个页面以及渲染一个指定的模板。显示列表和某个特定对象的详细内容页面。 第8章中提到的 event_list 和 entry_list 视图就是列表视图的一个例子。 一个单一的 event 页面就是我们所说的详细内容页面。呈现基于日期的数据的年/月/日归档页面,关联的详情页面,最新页面。 Django Weblogs (http://www.djangoproject.com/weblog/)的年、月、日的归档就是使用通用视图 架构的,就像是典型的新闻报纸归档。综上所述,这些视图为开发者日常开发中常见的任务提供了易用的接口。使用通用视图使用通用视图的方法是在URLconf文件中创建配置字典,然后把这些字典作为URLconf元组的第三个成员。 (对于这个技巧的应用可以参看第八章向视图传递额外选项。)例如,下面是一个呈现静态“关于”页面的URLconf:from django.conf.urls.defaults import *from django.views.generic.simple import direct_to_templateurlpatterns = patterns('', (r'^about/$', direct_to_template, { 'template': 'about.html' }))一眼看上去似乎有点不可思议,不需要编写代码的视图! 它和第八章中的例子完全一样:direct_to_template视图仅仅是直接从传递过来的额外参数获取信息并用于渲染视图。因为通用视图都是标准的视图函数,我们可以在我们自己的视图中重用它。 例如,我们扩展 about例子,把映射的URL从 /about//修改到一个静态渲染 about/.html 。 我们首先修改URL配置以指向新的视图函数:from django.conf.urls.defaults import *from django.views.generic.simple import direct_to_templatefrom mysite.books.views import about_pagesurlpatterns = patterns('', (r'^about/$', direct_to_template, { 'template': 'about.html' }), (r'^about/(\w+)/$', about_pages),)接下来,我们编写 about_pages 视图的代码:from django.http import Http404from django.template import TemplateDoesNotExistfrom django.views.generic.simple import direct_to_templatedef about_pages(request, page): try: return direct_to_template(request, template="about/%s.html" % page) except TemplateDoesNotExist: raise Http404()在这里我们象使用其他函数一样使用 direct_to_template 。 因为它返回一个HttpResponse对象,我们只需要简单的返回它就好了。 这里唯一有点棘手的事情是要处理找不到模板的情况。 我们不希望一个不存在的模板导致一个服务端错误,所以我们捕获TemplateDoesNotExist异常并且返回404错误来作为替代。这里有没有安全性问题?眼尖的读者可能已经注意到一个可能的安全漏洞: 我们直接使用从客户端浏览器得到的数据构造模板名称(template="about/%s.html" % page )。乍看起来,这像是一个经典的 目录跨越(directory traversal) 攻击(详情请看第20章)。 事实真是这样吗?完全不是。 是的,一个恶意的 page 值可以导致目录跨越,但是尽管 page 是 从请求的URL中获取的,但并不是所有的值都会被接受。 这就是URL配置的关键所在: 我们使用正则表达式 \w+ 来从URL里匹配 page ,而 \w 只接受字符和数字。 因此,任何恶意的字符 (例如在这里是点 . 和正斜线 / )将在URL解析时被拒绝,根本不会传递给视图函数。对象的通用视图direct_to_template 毫无疑问是非常有用的,但Django通用视图最有用的地方是呈现数据库中的数据。 因为这个应用实在太普遍了,Django带有很多内建的通用视图来帮助你很容易 地生成对象的列表和明细视图。让我们先看看其中的一个通用视图: 对象列表视图。 我们使用第五章中的 Publisher 来举例:class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() def __unicode__(self): return self.name class Meta: ordering = ['name']要为所有的出版商创建一个列表页面,我们使用下面的URL配置:from django.conf.urls.defaults import *from django.views.generic import list_detailfrom mysite.books.models import Publisherpublisher_info = { 'queryset': Publisher.objects.all(),}urlpatterns = patterns('', (r'^publishers/$', list_detail.object_list, publisher_info))这就是所要编写的所有Python代码。 当然,我们还需要编写一个模板。 我们可以通过在额外参数字典中包含一个template_name键来显式地告诉object_list视图使用哪个模板:from django.conf.urls.defaults import *from django.views.generic import list_detailfrom mysite.books.models import Publisherpublisher_info = { 'queryset': Publisher.objects.all(), 'template_name': 'publisher_list_page.html',}urlpatterns = patterns('', (r'^publishers/$', list_detail.object_list, publisher_info))在缺少template_name的情况下,object_list通用视图将自动使用一个对象名称。 在这个例子中,这个推导出的模板名称将是 "books/publish

[1] [2] [3]  下一页


Django 通用视图