本文翻譯自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