本文翻译自django1.8.2官方文档The view layer中的URLconfs段
URL dispatcher
一个简洁优雅的URL配置是一个高质量的WEB应用的重要细节.django允许自由设置URL,不受框架的限制.
没有必要用.php,.cgi,当然不要用0,2097,1-1-1928,00这种URL也是废话一句.
请参考Cool URIs don’t change, 万维网创造者蒂姆-伯纳斯-李所著,关于为什么URL应该简洁好用的精彩讨论.
Overview
要为你的应用设计URL,先新建一个Python模块叫URLconf(URL configuration).这个模块是纯Python代码,对URL patterns(简单的正则表达式)和python函数(你的views)做了简单映射.
这个映射按需要可长可短.它可以关联到其他映射.并且因为是纯python代码,所以可以动态的构造.
django也提供了根据URLs according转换成active language的方法.详情请看django国际化的文档.
How django process a request
当用户从你的django站点请求一个网页时,这是决定哪个python代码执行的规则:
- django会使用根URLconf.通常是ROOT_URLCONF的值,但是如果HttpRequest对象有一个属性叫urlconf(由中间件request processing设置),这个值就会取代ROOT_URLCONF.
- django加载python模块并寻找urlpatterns变量.这是一个django.conf.urls.url()实例列表.
- django按次序遍历每个URL pattern,直到找到一个匹配请求路径就会停止.
- 如果其中之一匹配,django就会导入并执行对应的视图(一个python函数或class based view).视图函数有以下参数:
- 一个HttpRequest实例.
- 如果匹配的正则表达式没有返回任何named groups,那么匹配项就会作为位置参数.
- The keyword arguments are made up of any named groups matched by the regular expression, overridden by any arguments specified in the optional kwargs argument to django.conf.urls.url().
- 如果没有正则表达式匹配,或者程序执行时有抛出异常,django就会调用一个处理异常的视图.请看下面的Error handling.
Example
下面是一个简单的URLconf:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
注意:
- 要改变URL的值,请使用小括号.
- 开头没有必要使用斜杠,因为每个URL自带.例如,用 ^articles,而不是^/articles.
- 正则表达式开头的’r’是可选项,但是推荐使用.它告诉python,字符串是’raw’ - 字符串里的字符不用转义
请求举例:
- 请求/articles/2005/03/匹配列表的第三项,django会调用views.month_archive(request, ‘2005’, ‘03’)
- /articles/2005/3没有匹配项,列表里的第三个正则需要2位数表示的月
- /articles/2003/匹配列表的第一项而不是第二项,因为正则要按顺序匹配,第一项是第一个匹配的.可以随时插入像这样的特殊情况来打乱顺序.这个例子中,django会调用函数views.special_case_2003(request)
- /articles/2003没有匹配项,因为所有正则都需要URL结尾的斜杠.
- /articles/2003/03/03匹配最后一项.django会调用函数views.article_detail(request, ‘2003’, ‘03’, ‘03’).
Named groups
上面的例子使用了简单的,没有命名的正则表达式组(通过小括号)来填充了许多URL并且将URL当作位置参数传递给一个视图函数.更高级的用法是,使用命名正则表达式组来填充URL,使用关键字参数来传递他们给视图函数.
在python的正则表达式里,命名正则表达式组是(?Ppattern),name是组的名字,pattern是正则.
这是上面的例子,用命名组重写:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]
这个例子和上个例子实现效果是一样的,只有少许区别:填充值通过关键字参数传给视图函数而不是位置参数.例如
- 请求/articles/2005/03/将调用函数views.month_archive(request, year=’2005’, month=’03’),而不是views.month_archive(request, ‘2005’, ‘03’)
- 请求/articles/2003/03/03/将调用函数views.article_detail(request, year=’2003’, month=’03’, day=’03’).
实际上,这就意味着你的url配置更明确,可能更少的参数位置错误,并且可以在视图函数的定义时标记参数.当然,这些好处是牺牲了简洁还来的,有些开发者认为命名组语法丑陋,太繁琐.
The matching/grouping algorithm(匹配/分组规则)
下面是URLconf解析器遵循的规则,有关命名组 vs 未命名组正则:
1. 如果有任何命名参数,那么就会忽略未命名参数.
2. 但是,会将所有的未命名参数当作位置参数传递.
在这两种情况下,任何其他的像Passing extra options to view functions的关键字参数,都会传递给视图.
What the URLconf searches against
URLconf搜索请求的URL,当作普通的python字符串处理.不包含GET或POST参数,或域名.
例如,在请求http://www.example.com/myapp/中,URLconf会寻找myapp/.
在请求http://www.example.com/myapp/?page=3中,URLconf会寻找myapp/3
URLconf不管请求方式.或者说,所有的请求方法-POST,GET,HEAD等-都通过同样的URL路由到相同的函数
Catpured arguments are always strings(填充的参数总是字符串)
所有的填充参数都当作普通Python字符串发送给视图,不管正则匹配到的是什么.例如,在这行URLconf:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
传给views.year_archive()的参数year是一个字符串.
而不是一个数字,哪怕[0-9]{4}只能匹配数字
Specifying defaults for view arguments
一个懒方法是在视图的参数里指定默认参数.这是一个URLconf和视图的例子:
# URLconf
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]
# View(in blog/views.py)
def page(request, num='1'):
# 根据num,输出队形的博客条目
...
在上面的例子中,2个正则都指向同样的视图-views.page-但是第一个正则没有在填充任何参数.如果第一个正则匹配,page()函数会使用默认参数,num的值是’1’.如果第二个正则匹配,page()使用填充的num的值.
Performance(性能)
urlpatterns里的每个正则都会在第一次访问的时候编译.这就使得系统极快.
Syntax of the urlpatterns variable
urlpatterns是url()实例列表.
Error handling
当django没有找到匹配请求的URL,或当有异常抛出时,django会请求一个处理异常的视图.
这种情况下使用的视图由4个变量决定.对于大多数项目,其默认值就足够了,但如果要自己定制就要改写默认值.
详细细节请看customzing error views
这些值可以在根URLconf里指定.在其他URLconf里设置这些值无效.
这些值必须是可调用的方法,或者标识方法的有全路径的python函数,能处理错误情况.
这些变量是:
- handler400- 详情见 django.conf.urls.handler400
- handler403- 详情见 django.conf.urls.handler403
- handler404- 详情见 django.conf.urls.handler404
- handler500- 详情见 django.conf.urls.handler500