天天看點

Python自動化運維:Django之URL路由

準備

首先建立一個Django 項目

進入manage.py所在目錄後

此時我們建立了一個名為urlTest的項目,其中有兩個子產品的名稱分别為app1和app2。(樹目錄結構如下)

在settings.py中我們可以看到:

ROOT_URLCONF = 'urlTest.urls'

#浏覽器通路的所有的url都将在urlTest目錄下的urls.py中配置,

urls.py預設加入了admin子產品的url:

也即是說,每個url都映射到了一個指定的view函數,其中views中定義的函數接受一個request,并傳回一個response。

如對view的工作原理不清楚,可參考這裡request-response。

這裡寫代碼片

正規表達式與命名組

首先在app1子產品中通過正規表達式分别動态的比對年,年月,年月日類型的URL。

預設的情況下app1子產品中是沒有urls.py檔案,在我們建立了之後,還需要在urlTest的urls.py加上:

我用斜杆“/”作為分割年月日的符号,但是為什麼斜杆之前要加上圓括号呢?因為當加上圓括号的時候,django就能從URL中捕獲這一個值并傳遞給相對應的views函數,當然使用的是位置傳參。

根據URL比對到指定的views函數後,我分别傳回了HttpResponse:

剛才我們在使用圓括号進行傳參的時候是位置傳參,那麼如果我們希望使用關鍵字傳參的時候該怎麼辦呢?

這時候我們就使用到了命名組,命名組的正規表達式文法是(?P<name>pattern),其中name是指傳遞參數的名字,pattern是指比對模式。

是以,下面的代碼與之前的正規表達式+圓括号是完全等效地:

最後值得注意的是在views函數中的參數是可以使用預設參數的,以及可以使用正規表達式進行不捕獲參數的設定(可在嵌套參數中使用),如文法(?:….)。

除了捕獲URL參數以外,我們還可以直接通過url函數傳輸額外的資料給view函數。

如果在包含include函數的url函數裡面傳輸額外的資料,那麼額外的資料将傳輸給被包含的urls.py的每一行url函數上。

URL模式與命名空間

在url patterns上裡面的每一個url函數就是一個URL模式,在django中使用類django.core.urlresolvers.RegexURLPattern來表示。

而url patterns就代表着一個URL分解器(url resolver),使用include函數包含其他的url配置子產品也是作為一個URL分解器來解析,在django中使用類django.core.urlresolvers.RegexURLResolver來表示。

命名空間主要分為兩種,分别是執行個體命名空間(instance namespace)以及應用命名空間(application namespace)。

為什麼需要命名空間呢?

在之前如果我們通過URL反查的話是通過URL模式中的name屬性來進行反查标記的,但是name屬性容易重複并且不利于複用,當我們要多次部署一個URL配置子產品的時候,就無法通過簡單的name屬性來進行标記了。

如何設定執行個體命名空間以及應用命名空間?

一般來說,同一應用下的不同執行個體應該具有相同的應用命名空間,但是,這并不意味着不同應用可以使用相同的執行個體命名空間,因為執行個體命名空間在你所有項目中都是唯一的。

URL反向解析

URL反向解析一般是通過reverse函數以及模闆中的url标記實作。

我們首先看看在django官方文檔中URL反向解析的機制:

除了最後一個視圖名作為name标記來識别,之前的每一個名稱首先是作為應用命名空間來識别的(第一條),如果找不到符合的應用命名空間則直接作為執行個體命名空間來識别(第五條)。

當識别出應用命名空間的時候,再看目前應用有沒有定義(即current_app,這裡比較容易引起誤解,這個目前應用并非應用命名空間,恰恰相反,它是指執行個體命名空間),如果定義了,直接在之前的已經确認的應用命名空間的所屬的執行個體命名空間清單下尋找current_app的值(第二條)。

如果在執行個體命名空間清單下找不到current_app的值,那麼它會尋找預設的執行個體命名空間,即名稱與應用命名空間相同的執行個體命名空間。(第三條)

如果連預設的執行個體命名空間都找不到,那麼django會傳回最後一個部署的執行個體命名空間的URL。(第四條)

我們還是通過具體的例子來說明反向解析機制吧。

之前的例子裡定義了app1子產品和app2子產品,再分别生成兩個它們的執行個體。

在pdb的測試環境下我們使用reverse函數分别确定。

我們可以看到,執行個體命名空間能夠唯一确定整個項目的URL。

當我們使用應用命名空間的時候,django反向解析機制在沒有提供current_app的情況下又找不到預設的執行個體命名空間,隻能傳回最後一個部署的執行個體命名空間。

在提供了執行個體命名空間之後,即使是使用應用命名空間也能唯一确定URL。

最後我們重新添加預設執行個體命名空間。

最後還要提醒的是,千萬不要以為不同應用下可以有相同的執行個體,namespace必須是unique!

本文轉自 炫維 51CTO部落格,原文連結:http://blog.51cto.com/xuanwei/1980442