视图和URL配置

来源:互联网 发布:sql视频教程 编辑:程序博客网 时间:2024/05/29 13:19

一、视图

    在mysite/misite(和__init__.py一个目录)中,创建一个view.py文件:

from django.http import HttpResponsedef hello(request):    return HttpResponse("Hello,World!")

    每个视图函数至少要有一个参数,通常被叫作request。 这是一个触发这个视图、包含当前Web请求信息的对象,是类django.http.HttpRequest的一个实例。在这个示例中,虽然不用request做任何事情,然而它仍必须是这个视图的第一个参数。一个视图就是Python的一个函数。这个函数第一个参数的类型是HttpRequest;它返回一个HttpResponse实例。为了使一个Python的函数成为一个Django可识别的视图,它必须满足这两个条件。

    执行 django-admin.py startproject 时,该脚本会自动建立一份 URLconf(即 urls.py 文件):

如果想在URLconf中加入URL和view,只需增加映射URL模式和view功能的Python tuple即可. 这里演示如何添加view中hello功能。

from django.conf.urls.defaults import *from mysite.views import hellourlpatterns = patterns('',    ('^hello/$', hello),)

    对urls.py文件做了两处修改:

  1. 从模块 (在 Python 的 import 语法中, mysite/views.py 转译为mysite.views ,mysite称为包) 中引入了hello 视图。
  2. 为urlpatterns加上一行:(‘^hello/$’, hello),这行被称作URLpattern,它是一个Python的元组。元组中第一个元素是模式匹配字符串(正则表达式);第二个元素是那个模式将使用的视图函数。

简单来说,就是告诉 Django,所有指向 URL /hello/ 的请求都应由hello 这个视图函数来处理。


Django在检查URL模式前,移除每一个申请的URL开头的斜杠(/)。 这意味着为/hello/写URL模式不用包含斜杠(/)。如果有人申请访问/hello(尾部没有斜杠/)会怎样。 因为URL模式要求尾部有一个斜杠(/),那个申请URL将不匹配。 然而,默认地,任何不匹配或尾部没有斜杠(/)的申请URL,将被重定向至尾部包含斜杠的相同字眼的URL。 (这是受配置文件setting中APPEND_SLASH项控制的)。


另外需要注意的是,hello视图函数是作为一个对象传递,而不是在调用它。 这是 Python (及其它动态语言的) 的一个重要特性: 函数是一级对象(first-class objects), 也就是说可以像传递其它变量一样传递它们。

二、Django是如何处理请求的

一切都从settings.py开始。运行python manage.py runserver后,脚本将在于manage.py同一个目录下查找名为settings.py的文件。这个文件包含了所有有关这个Django项目的配置信息,均大写: TEMPLATE_DIRS , DATABASE_NAME, 等. 最重要的设置是ROOT_URLCONF,它将作为URLconf告诉Django在这个站点中那些Python的模块将被用到。当运行python manage.py run server后,生成的settings.py文件中的ROOT_URLCONF指向自动生成的urls.py文件,settings.py文件中会有ROOT_URLCONF=’mysite.urls‘这样一行语句。当访问 URL /hello/ 时,Django 根据ROOT_URLCONF 的设置装载 URLconf 。 然后按顺序逐个匹配URLconf里的URLpatterns,直到找到一个匹配的。 当找到这个匹配 的URLpatterns就调用相关联的view函数,并把HttpRequest 对象作为第一个参数。

总结如下:
  1. 转入/hello/请求
  2. Django根据ROOT_CONF来决定根URLCONF
  3. Django根据在URLCONF中的所有URL模式中,查找第一个匹配/hello/的条目
  4. 如果找到匹配,将调用相应的视图函数
  5. 视图函数返回一个HttpResponse对象
  6. Django把HttpResponse转换成合适的http response,在网页中显示出来。

三、动态视图

构建一个显示时间的/time/网页,相应的view函数进行了修改:

在URL的匹配条目中添加('^time/$',current_time)后,显示结果如下:



四、动态URL

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

之前用PHP的时候可能会用到查询字符串参数, 就像/time/plus?hours=3这样,偏差小时在查询字符串中被参数hours指定(问号后面的是参数)。但是Django的一个核心理念就是URL必须看起来漂亮。 URL/time/plus/3/ 更加清晰, 更简单,也更有可读性,可以很容易的大声念出来,因为它是纯文本,没有查询字符串那么 复杂。 漂亮的URL就像是高质量的Web应用的一个标志。Django的URL配置系统可以使你很容易的设置漂亮的URL。

使用通配符来匹配任意数量的时差
urlpatterns = patterns('',    # ...    (r'^time/plus/(\d+)/$', hours_ahead),    # ...)

这个URL模式将匹配类似 /time/plus/2/ ,/time/plus/25/ ,甚至/time/plus/100000000000/ 的任何URL。

hous_ahead代码:

from django.http import Http404, HttpResponseimport datetimedef hours_ahead(request, offset):    try:        offset = int(offset)    except ValueError:        raise Http404()    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)    return HttpResponse(html)

需要注意的有两点:
  1. offset 是从匹配的URL里提取出来的。 例如:如果请求URL是/time/plus/3/,那么offset将会是3;如果请求URL是/time/plus/21/,那么offset将会是21。请注意:捕获值永远都是字符串(string)类型,而不会是整数(integer)类型,即使这个字符串全由数字构成(如:“21”)。
这里offset的名字可以随意命名,但是位置必须在hours_ahead的第二个参数,urls中的正则表达式会产生group,第二个参数会自动匹配到相应的group.

结果示例图:


P.S:
  1. 注意松耦合:模块化后,模块之间的修改尽量不相互影响,这样比较好进行维护。
  2. 之前一直放置print语句来进行调试,其实可以用 Django 出错页来做这些,而不用 print 语句。 在视图的任何位置,临时插入一个assertFalse 来触发出错页。 然后,你就可以看到局部变量和程序语句了。以hours_ahead为例:
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)

结果如下:



0 0