核心是middleware(中間件),django全部的請求、返回都由中間件來完成。html
中間件,就是處理HTTP的request和response的,相似插件,好比有Request中間件、view中間件、response中間件、exception中間件等,Middleware都須要在 「project/settings.py」 中 MIDDLEWARE_CLASSES 的定義。大體的程序流程圖以下所示:node
首先,Middleware都須要在 「project/settings.py」 中 MIDDLEWARE_CLASSES 的定義, 一個HTTP請求,將被這裏指定的中間件從頭至尾處理一遍,暫且稱這些須要挨個處理的中間件爲處理鏈,若是鏈中某個處理器處理後沒有返回response,就把請求傳遞給下一個處理器;若是鏈中某個處理器返回了response,直接跳出處理鏈由response中間件處理後返回給客戶端,能夠稱之爲短路處理。python
Django 處理一個 Request 的過程是首先經過中間件,而後再經過默認的 URL 方式進行的。咱們能夠在 Middleware 這個地方把全部Request 攔截住,用咱們本身的方式完成處理之後直接返回 Response。所以瞭解中間件的構成是很是必要的。程序員
出於性能的考慮,每一個已啓用的中間件在每一個服務器進程中只初始化一次。也就是說 __init__() 僅在服務進程啓動的時候調用,而在針對單個 request 處理時並不執行。正則表達式
對一個 middleware 而言,定義 __init__() 方法的一般緣由是檢查自身的必要性。若是 __init__() 拋出異常 django.core.exceptions.MiddlewareNotUsed ,則 Django 將從 middleware 棧中移出該 middleware。數據庫
在中間件中定義 __init__() 方法時,除了標準的 self 參數以外,不該定義任何其它參數。django
這個方法的調用時機在 Django 接收到 request 以後,但仍未解析URL以肯定應當運行的 view 以前。Django 向它傳入相應的 HttpRequest 對象,以便在方法中修改。數組
process_request() 應當返回 None 或 HttpResponse 對象。瀏覽器
若是返回 None ,Django 將繼續處理這個 request,執行後續的中間件, 而後調用相應的 view。服務器
若是返回 HttpResponse 對象,Django 將再也不執行任何其它的中間件(無視其種類)以及相應的view。 Django將當即返回該 HttpResponse。
這個方法的調用時機在 Django 執行完 request 預處理函數並肯定待執行的 view 以後,但在 view 函數實際執行以前。
request:HttpRequest 對象。
callback:Django將調用的處理request的python函數. 這是實際的函數對象自己, 而不是字符串表述的函數名。
args:將傳入view的位置參數列表,但不包括 request 參數(它一般是傳入view的第一個參數)。
kwargs:將傳入view的關鍵字參數字典。
如同 process_request() , process_view() 應當返回 None 或 HttpResponse 對象。若是返回 None , Django將繼續處理這個 request ,執行後續的中間件, 而後調用相應的view。
若是返回 HttpResponse 對象,Django 將再也不執行 任何 其它的中間件(不論種類)以及相應的view,Django將當即返回。
這個方法的調用時機在 Django 執行 view 函數並生成 response 以後。
該處理器能修改 response 的內容;一個常見的用途是內容壓縮,如 gzip 所請求的 HTML 頁面。
這個方法的參數至關直觀: request 是 request 對象,而 response 則是從 view 中返回的 response 對象。
process_response() 必須返回 HttpResponse 對象. 這個 response 對象能夠是傳入函數的那一個原始對象(一般已被修改),也能夠是全新生成的。
這個方法只有在 request 處理過程當中出了問題而且 view 函數拋出了一個未捕獲的異常時纔會被調用。這個鉤子能夠用來發送錯誤通知,將現場相關信息輸出到日誌文件,或者甚至嘗試從錯誤中自動恢復。
這個函數的參數除了一向的 request 對象以外,還包括view函數拋出的實際的異常對象 exception 。
process_exception() 應當返回 None 或 HttpResponse 對象。
若是返回 None , Django將用框架內置的異常處理機制繼續處理相應request。
若是返回 HttpResponse 對象,Django 將使用該response對象,而短路框架內置的異常處理機制。
Django 和其餘 Web 框架的 HTTP 處理的流程大體相同,Django 處理一個 Request 的過程是首先經過中間件,而後再經過默認的 URL 方式進行的。咱們能夠在 Middleware 這個地方把全部 Request 攔截住,用咱們本身的方式完成處理之後直接返回 Response。
Django 的配置都在 「Project/settings.py」 中定義,能夠是 Django 的配置,也能夠是自定義的配置,而且都經過 django.conf.settings 訪問,很是方便。
最核心動做的是經過 django.core.management.commands.runfcgi 的 Command 來啓動,它運行 django.core.servers.fastcgi 中的 runfastcgi , runfastcgi 使用了 flup 的 WSGIServer 來啓動 fastcgi 。而 WSGIServer 中攜帶了 django.core.handlers.wsgi 的 WSGIHandler 類的一個實例,經過 WSGIHandler 來處理由Web服務器(好比Apache,Lighttpd等)傳過來的請求,此時纔是真正進入 Django 的世界。
當有 HTTP 請求來時, WSGIHandler 就開始工做了,它從 BaseHandler 繼承而來。 WSGIHandler 爲每一個請求建立一個 WSGIRequest 實例,而 WSGIRequest 是從 http.HttpRequest 繼承而來。接下來就開始建立 Response 了。
BaseHandler 的 get_response 方法就是根據 request 建立 response , 而 具體生成 response 的動做就是執行 urls.py 中對應的view函數了,這也是 Django能夠處理「友好URL」的關鍵步驟,每一個這樣的函數都要返回一個 Response 實例。此時通常的作法是經過 loader 加載 template 並生成頁面內 容,其中重要的就是經過 ORM 技術從數據庫中取出數據,並渲染到 Template 中,從而生成具體的頁面了。
Django 返回 Response 給 flup , flup 就取出 Response 的內容返回給 Web 服務器,由後者返回給瀏覽器。
總之, Django 在 fastcgi 中主要作了兩件事:處理 Request 和建立 Response , 而它們對應的核心就是「urls分析」、「模板技術」和「ORM技術」。
如圖所示,一個 HTTP 請求,首先被轉化成一個 HttpRequest 對象,而後該對象被傳遞給 Request 中間件處理,若是該中間件返回了Response,則直接傳遞給 Response 中間件作收尾處理。不然的話 Request 中間件將訪問 URL 配置,肯定哪一個 view 來處理,在肯定了哪一個 view 要執行,可是尚未執行該 view 的時候,系統會把 request 傳遞給 View 中間件處理器進行處理,若是該中間件返回了Response,那麼該 Response 直接被傳遞給 Response 中間件進行後續處理,不然將執行肯定的 View 函數處理並返回 Response,在這個過程當中若是引起了異常並拋出,會被 Exception 中間件處理器進行處理。
首先發生的是一些和 Django 有關(前期準備)的其餘事情,分別是:
若是是 Apache/mod_python 提供服務,request 由 mod_python 建立的 django.core.handlers.modpython.ModPythonHandler 實例傳遞給 Django。
若是是其餘服務器,則必須兼容 WSGI,這樣,服務器將建立一個 django.core.handlers.wsgi.WsgiHandler 實例。
這兩個類都繼承自 django.core.handlers.base.BaseHandler,它包含對任何類型的 request 來講都須要的公共代碼。
當上面其中一個處理器實例化後,緊接着發生了一系列的事情:
這個處理器(handler)導入你的 Django 配置文件。
這個處理器導入 Django 的自定義異常類。
這個處理器調用它本身的 load_middleware 方法,加載全部列在 MIDDLEWARE_CLASSES 中的 middleware 類而且內省它們。
最後一條有點複雜,咱們仔細瞧瞧。
一個 middleware 類能夠滲入處理過程的四個階段:request,view,response 和 exception。要作到這一點,只須要定義指定的、恰當的方 法:process_request,process_view, process_response 和 process_exception。middleware 能夠定義其中任何一個或全部這些方法,這取決於你想要它提供什麼樣的功能。
當處理器內省 middleware 時,它查找上述名字的方法,並創建四個列表做爲處理器的實例變量:
_request_middleware 是一個保存 process_request 方法的列表(在每一 種狀況下,它們是真正的方法,能夠直接調用),這些方法來自於任一個定義了它們的 middleware 類。
_view_middleware 是一個保存 process_view 方法的列表,這些方法來自於任一個定義了它們的 middleware 類。
_response_middleware 是一個保存 process_response 方法的列表,這些方法來自於任一個定義了它們的 middleware 類。
_exception_middleware 是一個保存 process_exception 方法的列表,這些方法來自於任一個定義了它們的 middleware 類。
如今處理器已經準備好真正開始處理了,所以它給調度程序發送一個信號 request_started(Django 內部的調度程序容許各類不一樣的組件聲明它們正在幹 什麼,並能夠寫一些代碼監聽特定的事件。關於這一點目前尚未官方的文檔, 但在 wiki 上有一些註釋。)。接下來它實例化一個 django.http.HttpRequest 的子類。
根據不一樣的處理器,多是 django.core.handlers.modpython.ModPythonRequest 的一個實例,也多是 django.core.handlers.wsgi.WSGIRequest 的一個實例。須要兩個不一樣的類是因 爲 mod_python 和 WSGI APIs 以不一樣的格式傳入 request 信息,這個信息須要 解析爲 Django 可以處理的一個單獨的標準格式。
一旦一個 HttpRequest 或者相似的東西存在了,處理器就調用它本身的 get_response 方法,傳入這個 HttpRequest 做爲惟一的參數。這裏就是幾乎全部真正的活動發生的地方。
四、請求處理機制其二:Django中間件的解析
get_response 作的第一件事就是遍歷處理器的 _request_middleware 實例變量並調用其中的每個方法,傳入 HttpRequest 的實例做爲參數。
1 |
for middleware_method in self ._request_middleware: |
2 |
response = middleware_method(request) |
3 |
if response: |
4 |
break |
這些方法能夠選擇短路剩下的處理並當即讓 get_response 返回,經過返回自身的一個值(若是它們這樣作,返回值必須是 django.http.HttpResponse 的一個實例,後面會討 論到)。若是其中之一這樣作了,咱們會當即回到主處理器代碼,get_response 不會等着看其它 middleware 類想要作什麼,它直接返回,而後處理器進入 response 階段。
然而,更通常的狀況是,這裏應用的 middleware 方法簡單地作一些處理並決定是否增長,刪除或補充 request 的屬性。
假設沒有一個做用於 request 的 middleware 直接返回 response,處理器下一 步會嘗試解析請求的 URL。它在配置文件中尋找一個叫作 ROOT_URLCONF 的配 置,用這個配置加上根 URL /,做爲參數來建立 django.core.urlresolvers.RegexURLResolver 的一個實例,而後調用它的 resolve 方法來解析請求的 URL 路徑。
URL resolver 遵循一個至關簡單的模式。對於在 URL 配置文件中根據 ROOT_URLCONF 的配置產生的每個在 urlpatterns 列表中的條目,它會檢查請 求的 URL 路徑是否與這個條目的正則表達式相匹配,若是是的話,有兩種選擇:
若是這個條目有一個能夠調用的 include,resolver 截取匹配的 URL,轉到 include 指定的 URL 配置文件並開始遍歷其中 urlpatterns 列表中的 每個條目。根據你 URL 的深度和模塊性,這可能重複好幾回。
不然,resolver 返回三個條目:
匹配的條目指定的 view function;
一個 從 URL 獲得的未命名匹配組(被用來做爲 view 的位置參數);
一個關鍵 字參數字典,它由從 URL 獲得的任意命名匹配組和從 URLConf 中獲得的任 意其它關鍵字參數組合而成。
注意這一過程會在匹配到第一個指定了 view 的條目時中止,所以最好讓你的 URL 配置從複雜的正則過渡到簡單的正則,這樣能確保 resolver 不會首先匹配 到簡單的那一個而返回錯誤的 view function。
若是沒有找到匹配的條目,resolver 會產生 django.core.urlresolvers.Resolver404 異常,它是 django.http.Http404 例外的子類。後面咱們會知道它是如何處理的。
1 |
# Apply view middleware |
2 |
for middleware_method in self ._view_middleware: |
3 |
response = middleware_method(request, callback, callback_args, callback_kwargs) |
4 |
if response: |
5 |
break |
一旦知道了所需的 view function 和相關的參數,處理器就會查看它的 _view_middleware 列表,並調用其中的方法,傳入 HttpRequst,view function,針對這個 view 的位置參數列表和關鍵字參數字典。
還有,Middleware 有可能介入這一階段並強迫處理器當即返回。
若是處理過程這時候還在繼續的話,處理器會調用 view function。Django 中的 Views 不很嚴格由於它只須要知足幾個條件:
必須能夠被調用。
必須接受 django.http.HttpRequest 的實例做爲第一位值參數。
必須能產生一個異常或返回 django.http.HttpResponse 的一個實例。
除了這些,你就能夠天馬行空了。儘管如此,通常來講,views 會使用 Django 的 database API 來建立,檢索,更新和刪除數據庫的某些東西,還會加載並渲染一個模板來呈現一些東西給最終用戶。
Django 的模板系統有兩個部分:一部分是給設計師使用的混入少許其它東西的 HTML,另外一部分是給程序員使用純 Python。
從一個 HTML 做者的角度,Django 的模板系統很是簡單,須要知道的僅有三個結構:
變量引用。在模板中是這樣: {{ foo }}。
模板過濾。在上面的例子中使用過濾豎線是這樣:{{ foo|bar }}。一般這 用來格式化輸出(好比:運行 Textile,格式化日期等等)。
模板標籤。是這樣:{% baz %}。這是模板的「邏輯」實現的地方,你能夠 {% if foo %},{% for bar in foo %},等等,if 和 for 都是模板標籤。
變量引用以一種很是簡單的方式工做。若是你只是要打印變量,只要 {{ foo }},模板系統就會輸出它。這裏惟一的複雜狀況是 {{ foo.bar }},這時模板系 統按順序嘗試幾件事:
首先它嘗試一個字典方式的查找,看看 foo['bar'] 是否存在。若是存在, 則它的值被輸出,這個過程也隨之結束。
若是字典查找失敗,模板系統嘗試屬性查找,看看 foo.bar 是否存在。同 時它還檢查這個屬性是否能夠被調用,若是能夠,調用之。
若是屬性查找失敗,模板系統嘗試把它做爲列表索引進行查找。
若是全部這些都失敗了,模板系統輸出配置 TEMPLATE_STRING_IF_INVALID 的值,默認是空字符串。
模板過濾就是簡單的 Python functions,它接受一個值和一個參數,返回一個新的值。好比,date 過濾用一個 Python datetime 對象做爲它的值,一個標準的 strftime 格式化字符串做爲它的參數,返回對 datetime 對象應用了格式化字符 串以後的結果。
模板標籤用在事情有一點點複雜的地方,它是你瞭解 Django 的模板系統是如何真正工做的地方。
在內部,一個 Django 模板體現爲一個 「nodes」 集合,它們都是從基本的 django.template.Node 類繼承而來。Nodes 能夠作各類處理,但有一個共同點: 每個 Node 必須有一個叫作 render 的方法,它接受的第二個參數(第一個參 數,顯然是 Node 實例)是 django.template.Context 的一個實例,這是一個相似於字典的對象,包含全部模板能夠得到的變量。Node 的 render 方法必須返回 一個字符串,但若是 Node 的工做不是輸出(好比,它是要經過增長,刪除或修 改傳入的 Context 實例變量中的變量來修改模板上下文),能夠返回空字符串。
Django 包含許多 Node 的子類來提供有用的功能。好比,每一個內置的模板標籤都 被一個 Node 的子類處理(好比,IfNode 實現了 if 標籤,ForNode 實現了 for 標籤,等等)。全部內置標籤能夠在 django.template.defaulttags 找到。
實際上,上面介紹的全部模板結構都是某種形式的 Nodes,純文本也不異常。變 量查找由 VariableNode 處理,出於天然,過濾也應用在 VariableNode 上,標 籤是各類類型的 Nodes,純文本是一個 TextNode。
通常來講,一個 view 渲染一個模板要通過下面的步驟,依次是:
加載須要渲染的模板。這是由 django.template.loader.get_template 完成的,它能利用這許多方法中的任意一個來定位須要的模板文件。 get_template 函數返回一個 django.template.Template 實例,其中包含通過解析的模板和用到的方法。
實例化一個 Context 用來渲染模板。若是用的是 Context 的子類 django.template.RequestContext,那麼附帶的上下文處理函數就會自動添加在 view 中沒有定義的變量。Context 的構建器方法用一個鍵/值對的字 典(對於模板,它將變爲名/值變量)做爲它惟一的參數,RequestContext 則用 HttpRequest 的一個實例和一個字典。
調用 Template 實例的 render 方法,Context 對象做爲第一個位置參數。
Template 的 render 方法的返回值是一個字符串,它由 Template 中全部 Nodes 的 render 方法返回的值鏈接而成,調用順序爲它們出如今 Template 中的順序。
一旦一個模板完成渲染,或者產生了其它某些合適的輸出,view 就會負責產生一 個 django.http.HttpResponse 實例,它的構建器接受兩個可選的參數:
一個做爲 response 主體的字符串(它應該是第一位置參數,或者是關鍵字 參數 content)。大部分時間,這將做爲渲染一個模板的輸出,但不是必須 這樣,在這裏你能夠傳入任何有效的 Python 字符串。
做爲 response 的 Content-Type header 的值(它應該是第二位置參數, 或者是關鍵字參數 mine_type)。若是沒有提供這個參數,Django 將會使 用配置中 DEFAULT_MIME_TYPE 的值和 DEFAULT_CHARSET 的值,若是你沒有 在 Django 的全局配置文件中更改它們的話,分別是 「text/html」 和 「utf-8」。
若是 view 函數,或者其中的什麼東西,發生了異常,那麼 get_response(我知 道咱們已經花了些時間深刻 views 和 templates,可是一旦 view 返回或產生異常,咱們仍將重拾處理器中間的 get_response 方法)將遍歷它的 _exception_middleware 實例變量並調用那裏的每一個方法,傳入 HttpResponse 和這個 exception 做爲參數。若是順利,這些方法中的一個會實例化一個 HttpResponse 並返回它。
這時候有可能仍是沒有獲得一個 HttpResponse,這可能有幾個緣由:
view 可能沒有返回值。
view 可能產生了異常但沒有一個 middleware 能處理它。
一個 middleware 方法試圖處理一個異常時本身又產生了一個新的異常。
這時候,get_response 會回到本身的異常處理機制中,它們有幾個層次:
若是 exception 是 Http404 而且 DEBUG 設置爲 True,get_response 將 執行 view django.views.debug.technical_404_response,傳入 HttpRequest 和 exception 做爲參數。這個 view 會展現 URL resolver 試圖匹配的模式信息。
若是 DEBUG 是 False 而且異常是 Http404,get_response 會調用 URL resolver 的 resolve_404 方法。這個方法查看 URL 配置以判斷哪個 view 被指定用來處理 404 錯誤。默認是 django.views.defaults.page_not_found,但能夠在 URL 配置中給 handler404 變量賦值來更改。
對於任何其它類型的異常,若是 DEBUG 設置爲 True,get_response 將執 行 view django.views.debug.technical_500_response,傳入 HttpRequest 和 exception 做爲參數。這個 view 提供了關於異常的詳細 信息,包括 traceback,每個層次 stack 中的本地變量,HttpRequest 對象的詳細描述和全部無效配置的列表。
若是 DEBUG 是 False,get_response 會調用 URL resolver 的 resolve_500 方法,它和 resolve_404 方法很是類似,這時默認的 view 是 django.views.defaults.server_error,但能夠在 URL 配置中給 handler500 變量賦值來更改。
此外,對於除了 django.http.Http404 或 Python 內置的 SystemExit 以外的任 何異常,處理器會給調度者發送信號 got_request_exception,在返回以前,構建一個關於異常的描述,把它發送給列在 Django 配置文件的 ADMINS 配置中的每個人。
如今,不管 get_response 在哪個層次上發生錯誤,它都會返回一個 HttpResponse 實例,所以咱們回處處理器的主要部分。一旦它得到一個 HttpResponse 它作的第一件事就是遍歷它的 _response_middleware 實例變量並 應用那裏的方法,傳入 HttpRequest 和 HttpResponse 做爲參數。
01 |
finally : |
02 |
# Reset URLconf for this thread on the way out for complete |
03 |
# isolation of request.urlconf |
04 |
urlresolvers.set_urlconf( None ) |
05 |
06 |
try : |
07 |
# Apply response middleware, regardless of the response |
08 |
for middleware_method in self ._response_middleware: |
09 |
response = middleware_method(request, response) |
10 |
response = self .apply_response_fixes(request, response) |
注意對於任何想改變點什麼的 middleware 來講,這是它們的最後機會。
一旦 middleware 完成了最後環節,處理器將給調度者發送 信號 request_finished,對與想在當前的 request 中執行的任何東西來講,這是最後的調用。監聽這個信號的處理者會清空並釋聽任何使用中的資源。好比,Django 的 request_finished 監聽者會關閉全部數據庫鏈接。
這件事發生之後,處理器會構建一個合適的返回值送返給實例化它的任何東西 (如今,是一個恰當的 mod_python response 或者一個 WSGI 兼容的 response,這取決於處理器)並返回。
這就是 Django 如何處理一個 request。
前面幾個 Sections 介紹了關於 Django 請求(Request)處理的流程分析,咱們也瞭解到,Django 是圍繞着 Request 與 Response 進行處理,也就是無外乎「求」與「應」。
當請求一個頁面時,Django 把請求的 metadata 數據包裝成一個 HttpRequest 對象,而後 Django 加載合適的 view 方法,把這個 HttpRequest 對象做爲第一個參數傳給 view 方法。任何 view 方法都應該返回一個 HttpResponse 對象。
HttpRequest 對象表示來自某客戶端的一個單獨的 HTTP 請求。HttpRequest 對象是 Django 自動建立的。
它的屬性有不少,能夠參考 DjangoBook,比較經常使用的有如下幾個:
1. method 請求方法,如:
1 |
if request.method = = "POST" : |
2 |
...... |
3 |
elif request.mehtod = = "GET" : |
4 |
...... |
2. 類字典對象GET、POST
3. COOKIES,字典形式
4. user:
一個django.contrib.auth.models.User 對象表示當前登陸用戶,若當前用戶還沒有登陸,user會設爲django.contrib.auth.models.AnonymousUser的一個實例。
能夠將它們與is_authenticated()區分開:
1 |
if request.user.is_authenticated(): |
2 |
.... |
3 |
else : |
4 |
.... |
5. session、字典形式
6. request.META
具體能夠參考《request.META裏包含了哪些數據?》。
request.META 是一個 Python 字典,包含了全部本次 HTTP 請求的 Header 信息,好比用戶 IP 地址和用戶 Agent(一般是瀏覽器的名稱和版本號)。注意,Header 信息的完整列表取決於用戶所發送的 Header 信息和服務器端設置的 Header 信息。 這個字典中幾個常見的鍵值有:
HTTP_REFERRER:進站前連接網頁,若是有的話
HTTP_USER_AGENT,用戶瀏覽器的user-agent字符串,若是有的話。 例如: "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" .
REMOTE_ADDR 客戶端IP,如:"12.345.67.89" 。(若是申請是通過代理服務器的話,那麼它多是以逗號分割的多個IP地址,如:"12.345.67.89,23.456.78.90" 。)
……
1 |
def request_test(request): |
2 |
context = {} |
3 |
try : |
4 |
http_referer = request.META[ 'HTTP_REFERRER' ] |
5 |
http_user_agent = request.META[ 'HTTP_USER_AGENT' ] |
6 |
remote_addr = request.META[ 'REMOTE_ADDR' ] |
7 |
return HttpResponse( '[http_user_agent]:%s,[remote_addr]=%s' % (http_user_agent,remote_addr)) |
8 |
except Exception,e: |
9 |
return HttpResponse( "Error:%s" % e) |
注意:GET、POST屬性都是django.http.QueryDict的實例,在DjangoBook可具體瞭解。
Request 和 Response 對象起到了服務器與客戶機之間的信息傳遞做用。Request 對象用於接收客戶端瀏覽器提交的數據,而 Response 對象的功能則是將服務器端的數據發送到客戶端瀏覽器。
好比在 view 層,通常都是如下列代碼結束一個 def:
1 |
return HttpResponse(html) |
2 |
return render_to_response( 'nowamagic.html' , { 'data' : data}) |
對於 HttpRequest 對象來講,是由 Django 自動建立, 可是,HttpResponse 對象就必須咱們本身建立。每一個 View 方法必須返回一個 HttpResponse 對象。HttpResponse 類在 django.http.HttpResponse。
1.構造 HttpRequest
HttpResponse 類存在於 django.http.HttpResponse,以字符串的形式傳遞給頁面。通常地,你能夠經過給 HttpResponse 的構造函數傳遞字符串表示的頁面內容來構造 HttpResponse 對象:
1 |
>>> response = HttpResponse( "Welcome to nowamagic.net." ) |
2 |
>>> response = HttpResponse( "Text only, please." , mimetype = "text/plain" ) |
可是若是想要增量添加內容, 你能夠把response看成filelike對象使用:
1 |
>>> response = HttpResponse() |
2 |
>>> response.write( "<p>Welcome to nowamagic.net.</p>" ) |
3 |
>>> response.write( "<p>Here's another paragraph.</p>" ) |
也能夠給 HttpResponse 傳遞一個 iterator 做爲參數,而不用傳遞硬編碼字符串。 若是你使用這種技術,下面是須要注意的一些事項:
iterator 應該返回字符串。
若是 HttpResponse 使用 iterator 進行初始化,就不能把 HttpResponse 實例做爲 filelike 對象使用。這樣作將會拋出異常。
最後,再說明一下,HttpResponse 實現了 write() 方法,能夠在任何須要 filelike 對象的地方使用 HttpResponse 對象。
2. 設置 Headers
你可使用字典語法添加,刪除 headers:
1 |
>>> response = HttpResponse() |
2 |
>>> response[ 'X-DJANGO' ] = "It's the best." |
3 |
>>> del response[ 'X-PHP' ] |
4 |
>>> response[ 'X-DJANGO' ] |
5 |
"It's the best." |
3. HttpResponse子類
主要是對一些40四、500等錯誤頁面的處理。
Table H-5. HttpResponse Subclasses | |
Class |
Description |
HttpResponseRedirect | 構造函數接受單個參數:重定向到的URL。能夠是全URL (e.g., 'http://search.yahoo.com/')或者相對URL(e.g., '/search/'). 注意:這將返回HTTP狀態碼302。 |
HttpResponsePermanentRedirect | 同HttpResponseRedirect同樣,可是返回永久重定向(HTTP 狀態碼 301)。 |
HttpResponseNotModified | 構造函數不須要參數。Use this to designate that a page hasn’t been modified since the user’s last request. |
HttpResponseBadRequest | 返回400 status code。 |
HttpResponseNotFound | 返回404 status code. |
HttpResponseForbidden | 返回403 status code. |
HttpResponseNotAllowed | 返回405 status code. 它須要一個必須的參數:一個容許的方法的list (e.g., ['GET','POST']). |
HttpResponseGone | 返回410 status code. |
HttpResponseServerError | 返回500 status code. |
固然,你也能夠本身定義不包含在上表中的HttpResponse子類。