Django——HttpRequest和HttpResponse
前面幾個 Sections 介紹了關於 Django 請求(Request)處理的流程分析,我們也瞭解到,Django 是圍繞著 Request 與 Response 進行處理,也就是無外乎“求”與“應”。
當請求一個頁面時,Django 把請求的 metadata 資料包裝成一個 HttpRequest 物件,然後 Django 載入合適的 view 方法,把這個 HttpRequest 物件作為第一個引數傳給 view 方法。任何 view 方法都應該返回一個 HttpResponse 物件。
HttpRequest
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 是一個 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可具體瞭解。
HttpResponse
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子類
主要是對一些404、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子類。
@csrf_exempt def test_ajax(request): if request.method =="GET": value = request.GET.get("name","ya") returnHttpResponseRedirect("/wechat/test/testA?name='yourname'"