编写你的第一个Django程序,第三部分
本文继续第二部分所讨论的内容。我们会继续开发网络投票程序并深入研究怎样创建公共接口——使用“视图”。
哲理
在Django程序中的“视图”是一种可以有着独立功能和模板的网页。比如,在一个博客程序中,你可能有以下视图:
l 博客首页——显示最新的日志。
l 日志详细页面——日志的永久链接页面。
l 基于年份的归档页面——显示给定年份所有有日志的月份。
l 基于月份的归档页面——显示给定月份所有有日志的日期。
l 基于日期的归档页面——显示给定日期所有的日志。
l 评论功能——处理日志的评论。
在本文的投票程序中,我们有下面的四种视图:
Poll归档页面——显示最新的所有投票。
Poll详细页面——显示一个投票的问题,可以进行投票但是不显示投票结果。
Poll结果页面——显示一个投票的结果。
投票功能——处理投票的选项。
在Django中,每个视图都是一个Python函数。
设计你的URL
编写视图的第一步就是设计你的URL结构。你需要创建一个叫做URLconf的Python模块。URLconf是连接指定的URL和Python代码的纽带。
当用户请求Django页面时,系统会查找ROOT_URLCONF设置,这是个Python模块的字符串。Django会加载这个模块并查找一个叫做urlpatterns的模块变量,这个变量是由遵循下面格式的元组所组成的序列:
(regular expression, Python callback function [, optional dictionary])
Django从第一个正则表达式开始进行迭代,将当前的URL与正则式进行比较直到找到匹配成功的纪录。
找到匹配的正则表达式,Django会调用对应的Python回调函数,并传入一个HttpRequest对象作为第一参数,任何根据正则式提取出的值将作为关键字参数传入,而optional dictionary中的值也会作为关键字参数传入。
要了解更多HttpRequest,请参考Request and response objects部分。要了解更多URLconfs,请参考URL dispatcher部分。
在第一部分里,当你运行python django-admin.py startproject mysite时,就已经在mysite/urls.py创建了一个默认的URLconf设置。它会自动将ROOT_URLCONF(在settings.py文件中)设置指向这个文件:
ROOT_URLCONF = 'mysite.urls'
下面是个例子。编辑mysite/urls.py,修改成如下代码:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^polls/$', 'mysite.polls.views.index'),
(r'^polls/(?P<poll_id>\d+)/$', 'mysite.polls.views.detail'),
(r'^polls/(?P<poll_id>\d+)/results/$', 'mysite.polls.views.results'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
)
我们要来审核一下上面的内容。当有人在你的网站上请求一个页面——例如“/polls/23/”,Django会加载mysite.url这个模块,因为ROOT_URLCONF设置已经指向它。在这个模块中,程序会查找一个叫做urlpatterns的变量并遍历其中的正则式。当它找到一个匹配“r'^polls/(?P<poll_id>\d+)/$'”的表达式时,程序会加载对应的模块:mysite.polls.views.detail。这个模块就是mysite/polls/views.py中的函数detail()。最后,程序会像下面这样调用detail()函数:
detail(request=<HttpRequest object>, poll_id='23')
poll_id=’23’这个部分来自(?P<poll_id>\d+)。用括号包围一个正则式会捕获匹配这个正则式的文字并将捕获到的文字作为视图中对应函数的参数传入;?P<poll_id>这个部分会给匹配到的内容赋予一个名称;\d+则是用来匹配一串数字的正则表达式。
由于URLconf设置都是正则表达式,所以你可以毫无限制地来使用它们。而且你也没有必要加上多余的URL部分,比如.php这样的扩展名——如果你像下面这样做,那只能说你天赋异禀、骨骼精奇,太异于常人了:
(r'^polls/latest\.php$', 'mysite.polls.views.index'),
真的,千万别这样,这太雷人了。
请注意一下,在正则式中并没有查找GET或是POST参数以及域名。例如,在请求http://www.example.com/myapp/时,URLconf会查找/myapp/。在请求http://www.example.com/myapp/?page=3时,URLconf还是查找/myapp/。
如果你在正则表达式上有困难,请看看维基百科和Python文档。当然,O’Reilly出版的图书“Mastering Regular Expressions”(Jeffrey Friedl著)也是非常不错的。
最后,一个有关性能上的提示:这些正则表达式在第一次加载URLconf的时候就进行编译。它们的速度超快。
编写你的第一个视图
现在我们还没创建任何视图——我们只是设置了URLconf而已。但是我们要先确认Django会遵循这些URLconf的设置。
启动Django开发服务器:
python manage.py runserver
现在访问http://localhost:8000/polls/,你应该会得到如下的错误信息:
ViewDoesNotExist at /polls/
Tried index in module mysite.polls.views. Error was: 'module'
object has no attribute 'index'
产生这个错误的原因是因为你还没有在mysite/polls/views.py编写index()函数。
试试访问“/polls/23/”、“/polls/23/results/”和“/polls/23/vote/”。这些错误信息会告诉你Django会调用哪些视图函数(调用失败的信息,因为你还没有编写任何视图)。
现在开始编写第一个视图。打开mysite/polls/views.py加入下面的Python代码:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the poll index.")
这就是个最简单的视图了。现在在浏览器里输入“/polls/”,就能看到输出的文字。现在加入下面的代码。它有点不一样,因为它带有一个参数(注意,这个参数是根据URLconf的正则表达式所捕获的内容):
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." % poll_id)
然后在浏览器里输入“/polls/34/”,就能在页面上看到你在URL中输入的ID值。
让视图真正发挥作用
每个视图函数都必须要做以下两件事情中的一件:返回一个包含页面内容的HttpResponse对象,或者抛出一个异常,比如Http404。剩下的就是你自己的工作了。
视图可以从数据库中读取纪录。它可以使用Django的模板系统,也可以使用第三方的Python模板系统。它可以生成PDF文件,输出XML,实时生成ZIP文件等等,使用Python库你可以做任何你想做的事情。
而Django想要的就是个HttpResponse对象,或者是个异常。
这真的很方便,现在我们用上第一部分提到过的数据库API来做点东西。修改一下index()视图函数,让它显示最新的5个投票问题,每个问题之间用逗号问分割并按照发布时间降序排列:
from mysite.polls.models import Poll
from django.http import HttpResponse
def index(request):
latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
output = ', '.join([p.question for p in latest_poll_list])
return HttpResponse(output)
但是这有个问题,页面的设计是在代码中写死的。如果你想改变页面的外观,就必须修改Python代码了。现在我们用Django模版系统将页面设计从Python代码中分离出来:
from django.template import Context, loader
from mysite.polls.models import Poll
from django.http import HttpResponse
def index(request):
latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
t = loader.get_template('polls/index.html')
c = Context({
'latest_poll_list': latest_poll_list,
})
return HttpResponse(t.render(c))
上面的代码会加载“polls/index.html”模板并传入一个context对象。这个context对象是一个关联了模板变量和Python对象的字典。
重新加载页面,你会看到一个错误信息:
TemplateDoesNotExist at /polls/
polls/index.html
现在还没创建模板呢。先在你的系统上建立个Django能够访问的文件夹。(Django就像你的服务器一样运行。)但是别把模板放在文档根目录下面。为了安全,你不能把它们设置为公共权限。然后修改settings.py中的TEMPLATE_DIRS加入刚才的创建的文件路径,让Django能够找到模板——就如同你在第二部分中所做的一样。
上面完成之后,在模板目录下面创建polls目录,然后在该目录下创建index.html文件。注意一下代码里的loader.get_template('polls/index.html')会加载[template_directory]/polls/index.html这个文件。
在模板文件中加入下面代码:
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
在浏览器中重新加载页面,你能看到一组列表中包含“What’s up”这个投票。
快捷方法:render_to_response()
加载模板,传入context对象并返回一个包含了渲染后的模板内容的HttpResponse对象是一套连贯的操作。Django提供了快捷方法来一步完成这些工作。下面是重写过的index()方法:
from django.shortcuts import render_to_response
from mysite.polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
return render_to_response('polls/index.html', {'latest_poll_list': latest_poll_list})
注意一下一旦我们在视图中使用了这些方法,就没有必要再导入load、Context和HttpResponse了。
render_to_response()方法接收模板名称作为第一参数,还可以接收一个字典作为可选的第二参数。改函数会根据传入的字典进行渲染模板,并返回HttpResponse对象。
分享到:
相关推荐
### Django Web 开发指南 #### 一、简介 《Django Web 开发指南》是一本专为希望使用Python进行Web应用开发的技术人员所撰写的书籍。本书由Jeff Forcier、Paul Bissex与Wesley Chun共同编写,三位作者都是在Python...
(简体中文) Python新手使用Django架站的16堂课 Python是目前很好受欢迎的程序设计语言 本书通过对Python语言使用很多的DjangoWebFramework的介绍 让读者可以轻松制作出全功能的动态网站。 本书分4部分 以16堂课来...
标题中提到的是“Django中文版 教程...综上所述,这份教程是全面介绍Django框架的中文版教材,不仅覆盖了Django的基本概念和操作,还深入探讨了高级主题和最佳实践,适合作为Python Web开发新手的入门指南和进阶参考。
### Django+Web开发指南 #### 一、简介与概述 《Django+Web开发指南》是一本关于Python Web框架Django的详细介绍书籍...无论你是刚接触Django的新手还是已经有一定经验的开发者,都可以从中获得有价值的信息和指导。
- **5.1 至 5.2 常见问题解答**:提供了关于 Django 使用过程中可能遇到的常见问题及解答,有助于新手快速解决问题。 通过以上概览,我们可以看出 Django 1.5 文档覆盖了从入门到进阶的所有知识点,并且提供了丰富...
**Django新手指南** Django是一个基于Python的高级Web框架,它强调了代码的简洁性和可重用性,使得开发者可以快速地构建高效、可扩展的Web应用。本指南将帮助初学者理解Django的基本概念,并逐步学习如何使用Django...
- **起步指南**:这部分是新手入门必备的教程,指导用户从零开始安装和配置 Django,并通过一个简单的示例应用程序来了解 Django 的基本结构和功能。 - **模型层**:解释了如何定义数据模型以及 Django ORM(对象...
本文档为 Django 1.5.3 版本提供了详尽的指导,旨在帮助开发者从零开始构建高质量的 Web 应用程序。文档由 Django 软件基金会发布于 2013 年 9 月 14 日。 #### 二、文档结构与主要内容 ##### 1. Django 文档概述 ...
1.9版本的Django官方文档提供了从零开始学习Django的“First steps”部分,这部分内容是为新手或者刚开始学习编程的开发者准备的,内容包括从Django的基础概览、安装到具体的教程,涵盖了请求和响应、模型和管理后台...
这部分通常会指导新手开发者如何设置开发环境,创建项目和应用,并编写简单的视图、模板和表单。 3. 模型和数据库 这部分会介绍如何定义数据模型,以及如何与数据库交互。Django提供了对象关系映射(ORM)系统,使得...
### Django后端新手如何初始化配置 对于初学者来说,Django 是一个功能强大且易于上手的 Python Web 开发框架。本文将详细指导你完成 Django 项目的初始化配置,并重点介绍如何连接数据库以及如何实现基本的增删改...
**Django Web开发指南** Django,一个基于Python的开源Web框架,因其高效、安全且易于使用的特点,已经成为全球开发者构建Web应用...无论你是Python新手还是资深开发者,这份指南都能成为你探索Django世界的宝贵资源。
**Django 1.11 文档 HTML 版** Django 1.11 是一个功能强大、高效...无论你是正在学习Django的新手,还是寻求特定问题解决方案的开发者,都能从中受益。记得时常查阅文档,它会成为你Django开发旅程中不可或缺的伙伴。
这部分内容通常会引导新手快速上手Django框架。它从Django的概览开始,提供了一个快速安装指南。接下来会手把手地指导用户编写第一个Django应用程序,通常包含多个部分(例如七个部分),帮助用户逐步构建起一个完整...
### Django框架学习指南 #### 一、概述与背景 Django 是一个高级的 Python Web 框架,它鼓励快速开发、干净且实用的设计。它遵循 MVC(模型-视图-控制器)架构模式,旨在通过减少重复代码来简化Web应用程序的开发...
首先,文档的标题“Django官方文档”表明了这是关于Django这一Python Web框架的权威指南。Django是一个高层次的Python Web框架,它促进了快速开发,并遵循MVC(模型-视图-控制器)设计模式。 接下来,文档的描述...
- **第5部分:测试**:提供Django测试框架的使用指南,包括单元测试、集成测试等内容。 - **第6部分:静态文件**:介绍如何在Django项目中管理和处理静态文件,如CSS、JavaScript等。 #### 三、高级教程 - **如何...
- 新手可以通过官方文档中的“编写你的第一个Django应用”系列指南快速上手,这部分内容通常会引导初学者一步步完成从安装Django到创建、运行并测试一个基础Web应用的整个过程。 3. 模型层(The model layer) - ...
这部分内容为新手提供了快速上手指南,包括如何安装 Django、创建项目、编写第一个应用等基础知识。 **4. 模型层 (The model layer)** 模型层是 Django 框架的核心之一,负责数据的存储和检索。这一章节详细介绍了...
文档的"Getting started"部分将指导新手用户如何安装Django,从编写第一个Django应用,到使用Django进行Web开发的各个层面。"How to install Django"部分则着重介绍了安装过程和配置环境的步骤。"Writing your first...