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 中去。