Django: 路由與視圖

簡介

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

Django這個詞來自吉普賽語,D不發音,中文一般翻爲姜戈,不過也有人至關搞笑的稱爲強哥。 官方發音點這裏:django

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應用程序進行。app

實現一個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或者WSGI。不過咱們仍是先跳過這個環節,開發階段,先找個簡單 的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/

相關文章
相關標籤/搜索