参考 http://djangobook.py3k.cn/2.0/

 

1. 视图和URL配置
基于前一篇已讲过写一个简单的测试项目了,这里又接着下去
首先,我们从 django.http 模块导入(import) HttpResponse 类
这里主要讲的是: 一个视图就是Python的一个函数。这个函数第一个参数的类型是HttpRequest;它返回一个HttpResponse实例。为了使一个Python的函数成为一个Django可识别的视图,它必须满足这两个条件。

你的第一个URLconf
运行 python manage.py runserver
URLconf 就像是 Django 所支撑网站的目录。
执行 django-admin.py startproject 时,该脚本会自动为你建了一份 URLconf(即 urls.py 文件)。
    *首先,我们从模块 (在 Python 的 import 语法中, blog/views.py 转译为 blog.views ) 中引入了 hello 视图。 (这假设blog/views.py在你的Python搜索路径上。关于搜索路径的解释,请参照下文。)

    *接下来,我们为urlpatterns加上一行: (‘^hello/$’, hello), 这行被称作URLpattern,它是一个Python的元组。元组中第一个元素是模式匹配字符串(正则表达式);第二个元素是那个模式将使用的视图函数。

讨论一下URLpattern的语法是值得的,因为它不是显而易见的。 虽然我们想匹配地址/hello/,但是模式看上去与这有点差别。 这就是为什么:
    Django在检查URL模式前,移除每一个申请的URL开头的斜杠(/)。 这意味着我们为/hello/写URL模式不用包含斜杠(/)。(刚开始,这样可能看起来不直观,但这样的要求简化了许多工作,如URL模式内嵌,我们将在第八章谈及。)

    模式包含了一个尖号(^)和一个美元符号($)。这些都是正则表达式符号,并且有特定的含义: 上箭头要求表达式对字符串的头部进行匹配,美元符号则要求表达式对字符串的尾部进行匹配。
   
    你大多数的URL模式会以^开始、以$结束,但是拥有复杂匹配的灵活性会更好。
   
总结一下:
   1. 进来的请求转入/hello/.
   2.Django通过在ROOT_URLCONF配置来决定根URLconf.
   3.Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。
   4.如果找到匹配,将调用相应的视图函数
   5.视图函数返回一个HttpResponse
   6. Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来
     
第二个视图: 动态内容
这个视图需要做两件事情: 计算当前日期和时间
为了让Django视图显示当前日期和时间,我们仅需要把语句:datetime.datetime.now()放入视图函数,然后返回一个HttpResponse对象即可。代码如下(views.py):
from django.http import HttpResponse
import datetime

def hello(request):
    
return HttpResponse("Hello world")

def current_datetime(request):
    now 
= datetime.datetime.now()
    html 
= "<html><body>It is now %s.</body></html>" % now
    
return HttpResponse(html)


添加上述代码之后,还要在urls.py中添加URL模式,以告诉Django由哪一个URL来处理这个视图。 用/time/之类的字眼易于理解:
from django.conf.urls.defaults import *
from blog.views import hello, current_datetime

urlpatterns 
= patterns('',
    (
'^hello/$', hello),
    (
'^time/$', current_datetime),
)


URL配置和松耦合
Django的URL配置就是一个很好的例子。 在Django的应用程序中,URL的定义和视图函数之间是松 耦合的,换句话说,决定URL返回哪个视图函数和实现这个视图函数是在两个不同的地方。 这使得 开发人员可以修改一块而不会影响另一块。
这一点就是我最喜欢的地方,非常的灵活,相对于dotnet和j2EE的非MVC项目来说,有过之无不及。
例如,考虑一下current_datetime视图。 如果我们想把它的URL 从原来的 /time/ 改变到 /currenttime/ ,我们只需要快速的修改一下URL配置即可, 不用担心这个函数的内部实现。同样的,如果我们想要修改这个函数的内部实现也不用担心会影响 到对应的URL。
此外,如果我们想要输出这个函数到 一些 URL, 我们只需要修改URL配置而不用 去改动视图的代码。 在这个例子里,current_datetime被两个URL使用。 这是一个故弄玄虚的例子,但这个方法迟早会用得上。
urlpatterns = patterns('',
    (
'^hello/$', hello),
    (
'^time/$', current_datetime),
    (
'^another-time-page/$', current_datetime),
)


第三个视图 动态URL
在我们的`` current_datetime`` 视图范例中,尽管内容是动态的,但是URL ( /time/ )是静态的。 在 大多数动态web应用程序,URL通常都包含有相关的参数。
让我们创建第三个视图来显示当前时间和加上时间偏差量的时间,设计是这样的: /time/plus/1/ 显示当前时间+1个小时的页面 /time/plus/2/ 显示当前时间+2个小时的页面 /time/plus/3/ 显示当前时间+3个小时的页面,以此类推。

如果你有其它web平台的开发经验(如PHP或Java),你可能会想:嘿!让我们用查询字符串参数吧! 就像/time/plus?hours=3里面的小时应该在查询字符串中被参数hours指定(问号后面的是参数)。

你 可以 在Django里也这样做 (如果你真的想要这样做,我们稍后会告诉你怎么做), 但是Django的一个核心理念就是URL必须看起来漂亮。 URL /time/plus/3/ 更加清晰, 更简单,也更有可读性,可以很容易的大声念出来,因为它是纯文本,没有查询字符串那么 复杂。 漂亮的URL就像是高质量的Web应用的一个标志。
那么,我们如何设计程序来处理任意数量的时差? 答案是:使用通配符(wildcard URLpatterns)。正如我们之前提到过,一个URL模式就是一个正则表达式。因此,这里可以使用d+来匹配1个以上的数字。
urlpatterns = patterns('',
    
# ...
    (r'^time/plus/\d+/$', hours_ahead),
    
# ...
)

备注
在建造Web应用的时候,尽可能多考虑可能的数据输入是很重要的,然后决定哪些我们可以接受。 在这里我们就设置了99个小时的时间段限制。
现在我们已经设计了一个带通配符的URL,我们需要一个方法把它传递到视图函数里去,这样 我们只用一个视图函数就可以处理所有的时间段了。 我们使用圆括号把参数在URL模式里标识 出来。 在这个例子中,我们想要把这些数字作为参数,用圆括号把 \d{1,2} 包围起来:
(r'^time/plus/(\d{1,2})/$', hours_ahead),

如果你熟悉正则表达式,那么你应该已经了解,正则表达式也是用圆括号来从文本里 提取 数据的。

最终的URLconf包含上面两个视图,如:

from django.conf.urls.defaults import *
from blog.views import hello, current_datetime, hours_ahead

urlpatterns 
= patterns('',
    (r
'^hello/$', hello),
    (r
'^time/$', current_datetime),
    (r
'^time/plus/(\d{1,2})/$', hours_ahead),
)

hours_ahead 和我们以前写的 current_datetime 很象,关键的区别在于: 它多了一个额外参数,时间差。以下是view代码:
完整的代码以下:
from django.http import Http404,HttpResponse
import datetime

def hello(request):
    
return HttpResponse("Hello world")

def current_datetime(request):
    now 
= datetime.datetime.now()
    html 
= "<html><title>show date</title><body>It is now %s.</body></html>" % now
    
return HttpResponse(html)

def hours_ahead(request, offset):
    
try:
        offset 
= int(offset)
    
except ValueError:
        
raise Http404()
    dt 
= datetime.datetime.now() + datetime.timedelta(hours=offset)
    
#assert False
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    
return HttpResponse(html)

###以上的代码在mac下面跑都可以成功的。

posted on 2011-03-30 12:07  渔民  阅读(1675)  评论(2编辑  收藏  举报