第三章:网页基础篇
第一份视图:动态内容
创建一个显示当前日期和时间的网页。这是一个不错的 动态 网页范例,因为该页面的内容不是静态的。相反,其内容是随着计算(本例中是对当前时间的计算)的结果而变化的。这个简单的范例既不涉及数据库,也不需要任何用户输入,仅输出服务器的内部时钟。
实现代码:
1 from django.http import HttpResponse
2 import datetime
3
4 def current_datetime(request):
5 now = datetime.datetime.now()
6 html = "<html><body>It is now %s.</body></html>" % now
7 return HttpResponse(html)
URL 映射到视图
1、描述
URLconf 就像是 Django 所支撑网站的目录。它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表。你就是以这种方式告诉 Django,对于这个 URL 调用这段代码,对于那个 URL 调用那段代码。但必须记住的是视图函数必须位于 Python 搜索路径之中
所有URL映射到视图都在urls.py文件中配置
1 from django.conf.urls.defaults import *
2
3 urlpatterns = patterns('',
4 # Example:
5 # (r'^mysite/', include('mysite.apps.foo.urls.foo')),
6
7 # Uncomment this for admin:
8 # (r'^admin/', include('django.contrib.admin.urls')),
9 (r'^time/$', current_datetime),
)
代码描述:
-
第一行从 django.conf.urls.defaults 模块引入了所有的对象,其中包括了叫做 patterns 的函数。
-
第二行调用 patterns() 函数并将返回结果保存到 urlpatterns 变量。 patterns() 函数只传入了一个空字符串参数。其他代码行都被注释掉了。 (该字符串可用作视图函数的通用前缀,但目前我们将略过这种高级用法。)
上面第一个第一份视图:动态内容
就可以这样访问: http://127.0.0.1:8000/time/
URL正则表达式:
符号 匹配
. (dot) 任意字符
\d 任意数字
[A-Z] 任意字符,
A-Z (大写)
[a-z] 任意字符,
a-z (小写)
[A-Za-z] 任意字符,
a-z (不区分大小写)
+ 匹配一个或更多 (例如, \d+ 匹配一个或多个数字字符)
[^/]+ 不是/的任意字符
* 匹配0个或更多 (例如, \d* 匹配0个或更多数字字符)
{1,3} 匹配1个到3个(包含)
Django是怎么处理请求的
1、Django如何处理请求: 完整细节
通过 URLconf 解析到哪个视图函数来返回 HttpResponse 可以通过中间件(middleware) 来短路或者增强。关于中间件的细节将在第十五章详细谈论,这里给出 图3-1 让你先了解大体概念.
当服务器收到一个HTTP请求以后,一个服务器特定的 handler 会创建 HttpRequest 并传递给下一个组件并处理。
这个 handler 然后调用所有可用的Request或者View中间件。这些类型的中间件通常是用来增强 HttpRequest 对象来对一些特别类型的request做些特别处理。只要其中有一个返回 HttpResponse ,系统就跳过对视图的处理。
即便是最棒的程序员也会有出错的时候, 这个时候 异常处理中间件(exception middleware) 可以帮你的大忙。如果一个视图函数抛出异常,控制器会传递给异常处理中间件处理。如果这个中间件没有返回 HttpResponse ,意味着它不能处理这个异常,这个异常将会再次抛出。
即便是这样,你也不用担心。Django包含缺省的视图来生成友好的404 和 500 回应(response)。
最后, response middleware 做发送 HttpResponse 给浏览器之前的后处理或者清除请求用到的相关资源。
2、URL配置和松耦合
Django和URL配置背后的哲学: 松耦合 原则。简单的说,松耦合是一个重要的保证互换性的软件开发方法。如果两段代码是松耦合的,那么改动其中一段代码不会影响另一段代码,或者只有很少的一点影响。
3、404 错误
这个页面的功能不只是显示404的基本错误信息,它同样精确的告诉你Django使用了哪个URL配置和这个配置里的每一个模式。这样,你应该能了解到为什么这个请求会抛出404错误。
第二个视图:动态URL
在我们的第一个视图范例中,尽管内容是动态的,但是URL ( /time/ )是静态的。在大多数动态web应用程序,URL通常都包含有相关的参数。
让我们创建第二个视图来显示当前时间和加上时间偏差量的时间,设计是这样的: /time/plus/1/ 显示当前时间+1个小时的页面 /time/plus/2/ 显示当前时间+2个小时的页面 /time/plus/3/ 显示当前时间+3个小时的页面,以此类推。
新手可能会考虑写不同的视图函数来处理每个时间偏差量,URL配置看起来就象这样:
1 urlpatterns = patterns('',
2 (r'^time/$', current_datetime),
3 (r'^time/plus/1/$', one_hour_ahead),
4 (r'^time/plus/2/$', two_hours_ahead),
5 (r'^time/plus/3/$', three_hours_ahead),
6 (r'^time/plus/4//$', four_hours_ahead),
7 )
很明显,这样处理是不太妥当的。不但有很多冗余的视图函数,而且整个应用也被限制了只支持预先定义好的时间段,2小时,3小时,或者4小时。如果哪天我们要实现 5 小时,我们就不得不再单独创建新的视图函数和配置URL,既重复又混乱。我们需要在这里做一点抽象,提取一些共同的东西出来。
解决方案如下:
带通配符的URL匹配模式
1 from django.conf.urls.defaults import *
2 from mysite.views import current_datetime, hours_ahead
3
4 urlpatterns = patterns('',
5 (r'^time/$', current_datetime),
6 (r'^time/plus/\d+/$', hours_ahead),
7 )
让我们在URL模式里使用通配符,URL模式是一个正则表达式,使用正则表达式模式 \d+ 来匹配一个或多个数字
这个URL模式将匹配类似 /time/plus/2/ , /time/plus/25/ ,甚至 /time/plus/100000000000/ 的任何URL。更进一步,让我们把它限制在最大允许99个小时,这样我们就只允许一个或两个数字,正则表达式的语法就是 \d{1,2} :
(r'^time/plus/\d{1,2}/$', hours_ahead),