Django提供了干净优雅的 URL 方案,URL配置文件是一个标准的 python 文件,支持动态配置。它的本质就是URL模式与调用的视图函数之间的映射表,最简单的配置文件如下:
from django.conf.urls.defaults import * from sailing.manager.views import search urlaptterns = patterns('', url(r'^search$',search), )
上面使用的是传递函数对象的方式(在 python 中,函数是一级对象,你可以像传递其它变量一样传递它们。使用传递函数对象的方式,还可以对函数对象进行包装),下面使用的是传递字符串的方式:
from django.conf.urls.defaults import * urlaptterns = patterns('sailing.manager.views', url(r'^search/$','search'), )
如果使用字符串的方式,可以不用 import 相关模块,而且可以使用通用前缀(patterns 函数的第一个参数是一个字符串,表示一个视图函数的通用前缀)。当有不同的前缀时,还可以增加多个 patterns() 对象,然后相加即可,如:
from django.conf.urls.defaults import * urlaptterns = patterns('sailing.manager.views', url(r'^search/$','search'), ) urlaptterns += patterns('', url(r'^admin/', include(admin.site.urls)), )
大多数的URL模式会以 ^ 开始,以 $ 结束,如果在URL模式尾部有一个斜杠,表面上看是不匹配尾部不带斜杠的URL,但是默认地,尾部没有斜杠的URL如果不匹配任何模式,将被重定向至尾部包含斜杠的模式。所以在 urlpatterns 中配置URL时,应尽量在尾部带上斜杠。
另外,由于 urls.py 是标准的 python 文件,所以支持动态设定 urlpatterns,如只在DEBUG模式下有效的模式:
from django.conf import settings from django.conf.urls.defaults import * if settings.DEUG: urlpatterns = patterns('', (r'^search/','search'), )
URLconf 中,无命名正则表达式组中,如果想要捕获URL部分的数据,就加上小括号,Django 会将捕获的文本作为位置参数传递给视图函数。此外,还可以使用命名的正则表达式组来捕获URL,也要加上小括号,并且将其作为关键字参数传递给视图。命名的正则表达式组的语法是: (?P<name>pattern) ,它的优点是可读性强,而且可以在view函数中对参数重新排序,它的缺点是不够简洁。注意,在同一个 URLconf 中,命名组和非命名组不能同时存在,否则虽然不会抛出错误,但可能有会意想不到的问题,所以请尽量避免。
除了在URL模式中传递参数之外,patterns() 函数中每一个 URLconf 可以有第三个元素,它是一个 dict 类型,表示关键字参数与传递的值(该值可以是字符串,也可以是任何类型的对象)。视图函数只关心它获得了参数,而不关心这些参数是捕捉到的,还是额外提供的。但是当冲突出现的时候,额外 URLconf 参数优先于捕捉值,如:
urlpatterns = patterns('', (r'^mydata/(?P<id>\d+)/$', views.my_view, {'id':3}), )
则不管请求的URL中 id 的值是什么,都只会将 id = 3 传递到视图函数中。每个被捕获的参数都是作为字符串发送到视图函数中的,而不管正则表达式中的格式,所以在视图函数中,你可能需要做一些类型转换(但可能不需要捕捉异常,因为 URLconf 的正则表达式已经确保只有该类型的字符串才能传到这个视图中)。
还有一个细节是视图函数中的参数可以有默认值,这样一来,可以做一些动态的功能;相应的,也可以使用 python 可变参数的特性(参数前面有一个*号,表示传递的参数保存为一个 tuple,参数前有两个*号,表示传递的关键字参数保存为一个字典)
在 URLconf 中,除了可以包装匹配的函数对象之外,还可以通过 include 包含其它 URLconf 。每当 Django 遇到 include() 时,它将URL中已匹配模式的文本去除,将剩余部分发往 include() 中指定的 URLconf 进一步处理。URLconf 的第三个参数(额外视图函数的参数),也可以传递到 include() 中指定的 URLconf 中去。