django HttpRequest物件
每當一個使用者請求傳送過來,Django將HTTP資料包中的相關內容,打包成為一個HttpRequest物件,並傳遞給每個檢視函式作為第一位置引數,也就是request,供我們呼叫。
HttpRequest物件中包含了非常多的重要的資訊和資料,應該熟練掌握它。
類定義:class HttpRequest[source]
一、屬性
HttpRequest物件的大部分屬性是隻讀的,除非特別註明。
1. HttpRequest.scheme
字串型別,表示請求的協議種類,'http'或'https'。
2. HttpRequest.body
bytes型別,表示原始HTTP請求的正文。它對於處理非HTML形式的資料非常有用:二進位制影象、XML等。如果要處理常規的表單資料,應該使用HttpRequest.POST。
還可以使用類似讀寫檔案的方式從HttpRequest中讀取資料,參見HttpRequest.read()。
3. HttpRequest.path
字串型別,表示當前請求頁面的完整路徑,但是不包括協議名和域名。例如:"/music/bands/the_beatles/"。這個屬性,常被用於我們進行某項操作時,如果不通過,返回使用者先前瀏覽的頁面。非常有用!
4. HttpRequest.path_info
在某些Web伺服器配置下,主機名後的URL部分被分成指令碼字首部分和路徑資訊部分。path_info
屬性將始終包含路徑資訊部分,不論使用的Web伺服器是什麼。使用它代替path可以讓程式碼在測試和開發環境中更容易地切換。
例如,如果應用的WSGIScriptAlias設定為/minfo
,那麼HttpRequest.path
等於/music/bands/the_beatles/
,而HttpRequest.path_info
為/minfo/music/bands/the_beatles/
。
5. HttpRequest.method
字串型別,表示請求使用的HTTP方法。預設為大寫。 像這樣:
if request.method == 'GET': do_something() elif request.method == 'POST': do_something_else()
通過這個屬性來判斷請求的方法,然後根據請求的方法不同,在檢視中執行不同的程式碼。
6. HttpRequest.encoding
字串型別,表示提交的資料的編碼方式(如果為None 則表示使用DEFAULT_CHARSET
設定)。 這個屬性是可寫的,可以通過修改它來改變表單資料的編碼。任何隨後的屬性訪問(例如GET或POST)將使用新的編碼方式。
7. HttpRequest.content_type
Django1.10中新增。表示從CONTENT_TYPE
頭解析的請求的MIME型別。
8. HttpRequest.content_params
Django 1.10中新增。包含在CONTENT_TYPE
標題中的鍵/值引數字典。
9 HttpRequest.GET
一個類似於字典的物件,包含GET請求中的所有引數。 詳情參考QueryDict文件。
10. HttpRequest.POST
一個包含所有POST請求的引數,以及包含表單資料的字典。 詳情請參考QueryDict文件。 如果需要訪問請求中的原始或非表單資料,可以使用HttpRequest.body
屬性。
注意:請使用if request.method == "POST"
來判斷一個請求是否POST型別,而不要使用if request.POST
。
POST中不包含上傳檔案的資料。
11. HttpRequest.COOKIES
包含所有Cookie資訊的字典。 鍵和值都為字串。可以類似字典型別的方式,在cookie中讀寫資料,但是注意cookie是不安全的,因此,不要寫敏感重要的資訊。
12. HttpRequest.FILES
一個類似於字典的物件,包含所有上傳的檔案資料。 FILES中的每個鍵為<input type="file" name="" />
中的name屬性值。 FILES中的每個值是一個UploadedFile
。
要在Django中實現檔案上傳,就要靠這個屬性!
如果請求方法是POST且請求的<form>
中帶有enctype="multipart/form-data"
屬性,那麼FILES將包含上傳的檔案的資料。 否則,FILES將為一個空的類似於字典的物件,屬於被忽略、無用的情形。
13. HttpRequest.META
包含所有HTTP頭部資訊的字典。 可用的頭部資訊取決於客戶端和伺服器,下面是一些示例:
- CONTENT_LENGTH —— 請求正文的長度(以字串計)。
- CONTENT_TYPE —— 請求正文的MIME型別。
- HTTP_ACCEPT —— 可接收的響應
Content-Type
。 - HTTP_ACCEPT_ENCODING —— 可接收的響應編碼型別。
- HTTP_ACCEPT_LANGUAGE —— 可接收的響應語言種類。
- HTTP_HOST —— 客服端傳送的Host頭部。
- HTTP_REFERER —— Referring頁面。
- HTTP_USER_AGENT —— 客戶端的
user-agent
字串。 - QUERY_STRING —— 查詢字串。
- REMOTE_ADDR —— 客戶端的IP地址。想要獲取客戶端的ip資訊,就在這裡!
- REMOTE_HOST —— 客戶端的主機名。
- REMOTE_USER —— 伺服器認證後的使用者,如果可用。
- REQUEST_METHOD —— 表示請求方法的字串,例如"GET" 或"POST"。
- SERVER_NAME —— 伺服器的主機名。
- SERVER_PORT —— 伺服器的埠(字串)。
以上只是比較重要和常用的,還有很多未列出。
從上面可以看到,除CONTENT_LENGTH
和CONTENT_TYPE
之外,請求中的任何HTTP頭部鍵轉換為META鍵時,都會將所有字母大寫並將連線符替換為下劃線最後加上HTTP_
字首。所以,一個叫做X-Bender
的頭部將轉換成META中的HTTP_X_BENDER
鍵。
13. HttpRequest.resolver_match
代表一個已解析的URL的ResolverMatch例項。
二、可自定義的屬性
Django不會自動設定下面這些屬性,而是由你自己在應用程式中設定並使用它們。
1. HttpRequest.current_app
表示當前app的名字。url模板標籤將使用其值作為reverse()
方法的current_app
引數。
2. HttpRequest.urlconf
設定當前請求的根URLconf
,用於指定不同的url路由進入口,這將覆蓋settings中的ROOT_URLCONF
設定。
將它的值修改為None,可以恢復使用ROOT_URLCONF
設定。
三、由中介軟體設定的屬性
Django的contrib應用中包含的一些中介軟體會在請求上設定屬性。
1. HttpRequest.session
SessionMiddleware中介軟體:一個可讀寫的,類似字典的物件,表示當前會話。我們要儲存使用者狀態,回話過程等等,靠的就是這個中介軟體和這個屬性。
2. HttpRequest.site
CurrentSiteMiddleware中介軟體:get_current_site()
方法返回的Site或RequestSite的例項,代表當前站點是哪個。
Django是支援多站點的,如果你同時上線了幾個站點,就需要為每個站點設定一個站點id。
3. HttpRequest.user
AuthenticationMiddleware中介軟體:表示當前登入的使用者的AUTH_USER_MODEL
的例項,這個模型是Django內建的Auth模組下的User模型。如果使用者當前未登入,則user將被設定為AnonymousUser
的例項。
可以使用is_authenticated
方法判斷當前使用者是否合法使用者,如下所示:
if request.user.is_authenticated: ... # Do something for logged-in users. else: ... # Do something for anonymous users.
四、方法
1. HttpRequest.get_host()[source]
根據HTTP_X_FORWARDED_HOST
和HTTP_HOST
頭部資訊獲取請求的原始主機。 如果這兩個頭部沒有提供相應的值,則使用SERVER_NAME
和SERVER_PORT
。
例如:"127.0.0.1:8000"
注:當主機位於多個代理的後面,get_host()
方法將會失敗。解決辦法之一是使用中介軟體重寫代理的頭部,如下面的例子:
from django.utils.deprecation import MiddlewareMixin
class MultipleProxyMiddleware(MiddlewareMixin): FORWARDED_FOR_FIELDS = [ 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST', 'HTTP_X_FORWARDED_SERVER', ] def process_request(self, request): """ Rewrites the proxy headers so that only the most recent proxy is used. """ for field in self.FORWARDED_FOR_FIELDS: if field in request.META: if ',' in request.META[field]: parts = request.META[field].split(',') request.META[field] = parts[-1].strip()
2. HttpRequest.get_port()[source]
使用META中HTTP_X_FORWARDED_PORT
和SERVER_PORT
的資訊返回請求的始發端口。
3. HttpRequest.get_full_path()[source]
返回包含完整引數列表的path。例如:/music/bands/the_beatles/?print=true
4. HttpRequest.build_absolute_uri(location)[source]
返回location的絕對URI形式。 如果location沒有提供,則使用request.get_full_path()
的值。
例如:"https://example.com/music/bands/the_beatles/?print=true"
注:不鼓勵在同一站點混合部署HTTP和HTTPS,如果需要將使用者重定向到HTTPS,最好使用Web伺服器將所有HTTP流量重定向到HTTPS。
5. HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)[source]
從已簽名的Cookie中獲取值,如果簽名不合法則返回django.core.signing.BadSignature。
可選引數salt用來為密碼加鹽,提高安全係數。 max_age
引數用於檢查Cookie對應的時間戳是否超時。
範例:
>>> request.get_signed_cookie('name') 'Tony' >>> request.get_signed_cookie('name', salt='name-salt') 'Tony' # assuming cookie was set using the same salt >>> request.get_signed_cookie('non-existing-cookie') ... KeyError: 'non-existing-cookie' >>> request.get_signed_cookie('non-existing-cookie', False) False >>> request.get_signed_cookie('cookie-that-was-tampered-with') ... BadSignature: ... >>> request.get_signed_cookie('name', max_age=60) ... SignatureExpired: Signature age 1677.3839159 > 60 seconds >>> request.get_signed_cookie('name', False, max_age=60) False
6. HttpRequest.is_secure()[source]
如果使用的是Https,則返回True,表示連線是安全的。
7. HttpRequest.is_ajax()[source]
如果請求是通過XMLHttpRequest生成的,則返回True。
這個方法的作用就是判斷,當前請求是否通過ajax機制傳送過來的。
8. HttpRequest.read(size=None)[source]
9. HttpRequest.readline()[source]
10. HttpRequest.readlines()[source]
11. HttpRequest.xreadlines()[source]
12. HttpRequest.iter()
上面的幾個方法都是從HttpRequest例項讀取檔案資料的方法。
可以將HttpRequest例項直接傳遞到XML解析器,例如ElementTree:
import xml.etree.ElementTree as ET
for element in ET.iterparse(request): process(element)