Django:路由與檢視

langyahappy發表於2015-11-10

簡介

Django框架是美國World Company(世界公司?NB)的工程師Adrian Holovaty和Simon Willison在開發其公司執行的新聞網站(LJWorld.com、Lawrence.com、KUsports.com ) 過程中,逐漸完善豐富而成,2005年開源,是迄今為止Python界名氣最大的Web框架。

Django這個詞來自吉普賽語,D不發音,中文通常翻為姜戈,不過也有人相當搞笑的稱為強哥。 官方發音點這裡:

Django框架取名於20世紀三十年代法國著名的爵士吉他手 Django Reinhardt —— 迄今為止最偉大的吉他手之一,儘管他的左手只有三個指頭:

Django-Reinhardt

穩定性:Django框架相當抗造,已經被Disqus, Instagram, Pinterest, Mozilla等機構廣泛採用,官方 說法是基於Django的站,可以支援每秒5萬次點選訪問。

產品定位:Django框架的定位是支援大中型動態網站的開發,提供了完備的擴充套件庫和工具集。不過 整個框架分解的比較清晰,如果你願意拋開Django的工具,深入到各個元件,會發現Django對各種 規模的應用,都能相當不錯的支援。

Django與WSGI

根據Python的慣例,Django不是一個完整的Web後端框架,它只負責開發WSGI應用程式 ,在生產環境中Django應用應當與一個WSGI伺服器配套,由WSGI伺服器負責網路通訊部分。

WSGI,全稱 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是為 Python 語言定義的Web伺服器和Web應用程式之間的一種簡單而通用的介面。

wsgi2.jpg

WSGI將Web服務分成兩個部分:伺服器和應用程式。WGSI伺服器只負責與網路相關的兩件事:接收瀏覽器的 HTTP請求、向瀏覽器傳送HTTP應答;而對HTTP請求的具體處理邏輯,則通過呼叫WSGI應用程式進行。

實現一個WSGI應用,只需要滿足3個要求:

是可呼叫的,比如是一個函式,或者是一個可呼叫類(具有call方法)的例項 WSGI應用應當返回一個可迭代(iterable)的值,比如字串列表 WSGI應用在返回之前,應當呼叫WSGI伺服器傳入的start_response函式傳送狀態碼和HTTP報文頭 最小WSGI應用

一種最簡單的滿足WSGI規約的應用程式需要實現一個指定形式的函式:

from wsgiref.simple_server import make_server

def wsgi_app(environ,start_response):
    start_response('200 OK',[('Context-Type','text/plain')])
    return 'such a tiny wsgi app!'

httpd = make_server('0.0.0.0',80,wsgi_app)    
httpd.serve_forever()  

environ是一個包含全部HTTP請求資訊的字典/Dict,由WSGI伺服器解包HTTP請求生成。

建立WSGI應用物件

Django框架對一個WSGI應用的結構進行了分解,有些部件由框架完成,有些部分需要 開發者實現。因此,開發一個基於Django框架的Web應用,事實上就是填充Django框架 所約定的需要由開發者完成的部件。

根據Django約定,一個WSGI應用裡最核心的部件有兩個:路由表和檢視。Django框架 的核心功能就是路由:根據HTTP請求中的URL,查詢路由表,將HTTP請求分發到 不同的檢視去處理:

hello.jpg

需要指出的是,在Django框架中,由於應用(application)有特定的含義,後續我們 將使用Django專案來表示Django框架中的WSGI應用物件。

建立WSGI應用物件很簡單,這通過呼叫get_wsgi_application()函式來完成。 這個物件用來與WSGI伺服器對接:

from django.core.wsgi import get_wsgi_application
wsgi_app = get_wsgi_application()

全域性配置物件

不過有一點需要指出,Django框架嚴重依賴於一個全域性配置物件settings來定製 其行為,因此,我們需要在建立WSGI應用物件之前,首先使用預設值初始化這個全域性 配置物件:

from django.conf import settings
settings.configure()

在示例程式碼中你看到,我們設定了其DEBUG 屬性為True,這將使Django框架執行在除錯狀態,輸出除錯資訊。

編寫檢視函式

DJango中的檢視就是一個標準的Python函式,不過由於Django框架要呼叫 這個函式,因此,作為檢視的函式有兩個約定需要滿足:

view.jpg

輸入 :第一個引數是一個HttpRequest物件,這是Django框架對一個HTTP請求 的完整封裝,檢視函式從這個物件中提取請求中的資訊

輸出 :返回值應當是一個HttpResponse物件,Django框架將基於這個返回 的物件完成對WSGI伺服器的響應

一個簡單的檢視函式看起來就是這樣:

def v_index(req):
    return HttpResponse('Hello,World!')

檢視函式通常是由框架發起呼叫的,我們不需要直接呼叫檢視函式。不過這並不是被禁止 的,有時候(比如自動測試)還有用處。模仿框架構造一個HttpRequest物件,傳給檢視 函式就行了:

req = HttpRequest()
print v_index(req)

定義路由表

Django框架根據HTTP請求的URL來找到對應的檢視函式,很自然的,路由表 使用一個列表物件,其中每一項記錄一種URL模式與一個檢視函式的對應關係:

urlpatterns = [
    url(r'^$',v_index),
    url(r'^about/$',v_about),
]

url()函式用來生成一個路由項,第一個引數是一個正規表示式,用來匹配 HTTP請求的URL,字首r用來防止正則字串被轉義;第二個引數就是我們定義 的檢視函式。

如果你對正規表示式很熟悉,可能會有一點疑問,為什麼上面的正規表示式,都 不包含前面那個/?比如,如果使用者請求的URL是/about/,那麼我們的正則表達 式應當寫成^/about/$才對?

嗯,是這樣,簡單地說,是Django框架在使用你定義的路由表之前,已經吃掉了 那個字首的/...先這樣吧,回頭再細說這一點。

註冊路由表

在一個有點規模的應用中,可能會存在多個開發組,每個開發組維護單獨的一張路由表。 因此,在Django框架中,需要告訴Django框架使用那個路由表作為根路由表。

使用全域性配置物件的ROOT_URLCONF屬性來註冊根路由表,應當為這個屬性指定一個 具有urlpatterns變數的模組名,Django將動態匯入這個模組並使用其urlpatterns 變數的值作為路由表。

因此,通常情況下,總應該將路由表變數命名為urlpatterns。

對接WSGI伺服器

嚴格來講,到上一節課為止,一個Django專案就開發完了,剩下的事情就是 部署到生產環境中去了。

deploy.jpg

在生產環境中,你可以對接生產級的WSGI伺服器,比如:Apache + mod_wsgi, Gunicorn或者wWSGI。不過我們還是先跳過這個環節,開發階段,先找個簡單 的WSGI伺服器跑起來!

使用Python內建的簡單WSGI伺服器,引入、建立伺服器、執行即可:

from wsgiref.simple_server import make_server
httpd = make_server('0.0.0.0',80,wsgi_app)
httpd.serve_forever()

更多內容如URL分發、URL反向解析、檢視函式、請求與響應、中介軟體等以及本文練習請參考: http://www.hubwiz.com/course/562efe441bc20c980538e801/

相關文章