Django 使用Request 對象和Response 對象在系統間傳遞狀態。html
當請求一個頁面時,Django會創建一個包含請求元數據的 HttpRequest 對象。 當Django 加載對應的視圖時,HttpRequest 對象將做爲視圖函數的第一個參數。每一個視圖會返回一個HttpResponse 對象。python
本文檔對HttpRequest 和HttpResponse 對象的API 進行說明,這些API 定義在django.http 模塊中。程序員
class HttpRequestajax
屬性django
下面除非特別說明,全部屬性都認爲是隻讀的。會話(session) 屬性是個例外,須要注意。json
New in Django 1.7. 一個字符串,表示請求的方案(一般是http 或https)。跨域
一個字節字符串,表示原始HTTP 請求的正文。它對於處理非HTML 形式的數據很是有用:二進制圖像、XML等。 若是要處理常規的表單數據,應該使用HttpRequest.POST。數組
你也可使用」類文件「形式的接口從HttpRequest 中讀取數據。參見HttpRequest.read()。瀏覽器
一個字符串,表示請求的頁面的完整路徑,不包含域名。緩存
例如:"/music/bands/the_beatles/"
在某些Web 服務器配置下,主機名後的URL 部分被分紅腳本前綴部分和路徑信息部分。path_info 屬性將始終包含路徑信息部分,不論使用的Web 服務器是什麼。使用它代替path 可讓代碼在測試和開發環境中更容易地切換。
例如,若是應用的WSGIScriptAlias 設置爲"/minfo",那麼當path 是"/minfo/music/bands/the_beatles/" 時path_info 將是"/music/bands/the_beatles/"。
一個字符串,表示請求使用的HTTP 方法。必須使用大寫。例如:
if request.method == 'GET': do_something() elif request.method == 'POST': do_something_else()
一個字符串,表示提交的數據的編碼方式(若是爲None 則表示使用DEFAULT_CHARSET 設置)。這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。接下來對屬性的任何訪問(例如從GET 或 POST 中讀取數據)將使用新的encoding 值。若是你知道表單數據的編碼不在DEFAULT_CHARSET 中,則使用它。
一個相似於字典的對象,包含HTTP GET 的全部參數。詳情請參考下面的QueryDict 文檔。
一個包含全部給定的HTTP POST參數的類字典對象,提供了包含表單數據的請求。詳情請參考下面的QueryDict 文檔。若是須要訪問請求中的原始或非表單數據,可使用HttpRequest.body 屬性。
POST 請求能夠帶有空的POST 字典 —— 若是經過HTTP POST 方法請求一個表單可是沒有包含表單數據的話。所以,不該該使用if request.POST 來檢查使用的是不是POST 方法;應該使用if request.method =="POST"(參見上文)。
注意:POST 不包含上傳的文件信息。參見FILES。
Deprecated since version 1.7:使用更顯式的GET 和POST 代替。
一個相似於字典的對象,它首先搜索POST,而後搜索GET,主要是爲了方便。靈感來自於PHP 的$_REQUEST。
例如,若是GET = {"name": "john"} 而POST = {"age": '34'},REQUEST["name"] 將等於"john"以及REQUEST["age"] 將等於"34"。
強烈建議使用GET 和POST 而不要用REQUEST,由於它們更加明確。
一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。
一個相似於字典的對象,包含全部的上傳文件。FILES 中的每一個鍵爲<input type="file" name="" /> 中的name。更多信息參見管理文件。
注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會包含數據。不然,FILES 將爲一個空的相似於字典的對象。
一個標準的Python 字典,包含全部的HTTP 頭部。具體的頭部信息取決於客戶端和服務器,下面是一些示例:
從上面能夠看到,除CONTENT_LENGTH 和CONTENT_TYPE 以外,請求中的任何HTTP 頭部轉換爲META 的鍵時,都會將全部字母大寫並將鏈接符替換爲下劃線最後加上HTTP_ 前綴。因此,一個叫作X-Bender 的頭部將轉換成META 中的HTTP_X_BENDER 鍵。
一個AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。若是用戶當前沒有登陸,user 將設置爲django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過is_authenticated() 區分它們,像這樣:
if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.
user 只有當Django 啓用AuthenticationMiddleware 中間件時纔可用。
一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。
不是由Django 自身定義的,可是若是其它代碼(例如,自定義的中間件類)設置了它,Django 就會讀取它。若是存在,它將用來做爲當前的請求的Root URLconf,並覆蓋ROOT_URLCONF 設置。
一個ResolverMatch 的實例,表示解析後的URL。這個屬性只有在URL 解析方法以後才設置,這意味着它在全部的視圖中能夠訪問,可是在在URL 解析發生以前執行的中間件方法中不能夠訪問(好比process_request,但你可使用process_view 代替)。
方法
根據從HTTP_X_FORWARDED_HOST(若是打開USE_X_FORWARDED_HOST)和HTTP_HOST 頭部信息返回請求的原始主機。若是這兩個頭部沒有提供相應的值,則使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有詳細描述。
例如:"127.0.0.1:8000"
注
當主機位於多個代理的後面,get_host() 方法將會失敗。有一個解決辦法是使用中間件重寫代理的頭部,例以下面的例子:
class MultipleProxyMiddleware(object): 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()
這個中間件應該放置在全部依賴於get_host() 的中間件以前 —— 例如,CommonMiddleware 和CsrfViewMiddleware。
返回path,若是能夠將加上查詢字符串。
例如:"/music/bands/the_beatles/?print=true"
返回location 的絕對URI。若是location 沒有提供,則設置爲request.get_full_path()。
若是URI 已是一個絕對的URI,將不會修改。不然,使用請求中的服務器相關的變量構建絕對URI。
例如:"http://example.com/music/bands/the_beatles/?print=true"
HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
返回簽名過的Cookie 對應的值,若是簽名再也不合法則返回django.core.signing.BadSignature。若是提供default 參數,將不會引起異常並返回default 的值。
可選參數salt 能夠用來對安全密鑰強力攻擊提供額外的保護。max_age 參數用於檢查Cookie 對應的時間戳以確保Cookie 的時間不會超過max_age 秒。
示例:
>>> 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
若是請求時是安全的,則返回True;即請求是經過HTTPS 發起的。
若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查HTTP_X_REQUESTED_WITH 頭部是不是字符串'XMLHttpRequest'。大部分現代的JavaScript 庫都會發送這個頭部。若是你編寫本身的XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓is_ajax() 能夠工做。
若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的cache middleware, 你應該使用vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。
這幾個方法實現類文件的接口用於讀取HttpRequest· 實例。這使得能夠用流的方式讀取進來的請求。常見的使用常見是使用迭代的解析器處理一個大型的XML而不用在內存中構建一個完整的XML 樹。
根據這個標準的接口,一個HttpRequest 實例能夠直接傳遞給XML 解析器,例如ElementTree:
import xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element)
class QueryDict
在HttpRequest 對象中,GET 和POST 屬性是django.http.QueryDict 的實例,它是一個自定義的相似字典的類,用來處理同一個鍵帶有多個值。這個類的需求來自某些HTML 表單元素傳遞多個值給同一個鍵,<selectmultiple> 是一個顯著的例子。
request.POST 和request.GET 的QueryDict 在一個正常的請求/響應循環中是不可變的。若要得到可變的版本,須要使用.copy()。
方法
QueryDict 實現了字典的全部標準方法,由於它是字典的子類。下面列出了不一樣點:
基於query_string 實例化QueryDict 一個對象。
>>> QueryDict('a=1&a=2&c=3') <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
If query_string 沒被傳入, QueryDict 的結果 是空的 (將沒有鍵和值).
你所遇到的大部分 對象都是不可修改的,例如request.POST和request.GET。若是須要實例化你本身的能夠修改的對象,經過往它的__init__()方法來傳遞參數 mutable=True 能夠實現。 .
設置鍵和值的字符串都將從encoding 轉換爲unicode。若是沒有指定編碼的話,默認會設置爲DEFAULT_CHARSET.
Changed in Django 1.8:在之前的版本中,query_string 是一個必需的位置參數。
返回給出的key 的值。若是key 具備多個值,__getitem__() 返回最新的值。若是key 不存在,則引起django.utils.datastructures.MultiValueDictKeyError。(它是Python 標準KeyError 的一個子類,因此你仍然能夠堅持捕獲KeyError。)
設置給出的key 的值爲[value](一個Python 列表,它具備惟一一個元素value)。注意,這和其它具備反作用的字典函數同樣,只能在可變的QueryDict 上調用(如經過copy() 建立的字典)。
若是給出的key 已經設置,則返回True。它讓你能夠作if "foo" in request.GET 這樣的操做。
使用與上面__getitem__() 相同的邏輯,可是當key 不存在時返回一個默認值。
相似標準字典的setdefault() 方法,只是它在內部使用的是__setitem__()。
接收一個QueryDict 或標準字典。相似標準字典的update() 方法,可是它附加到當前字典項的後面,而不是替換掉它們。例如:
>>> q = QueryDict('a=1', mutable=True) >>> q.update({'a': '2'}) >>> q.getlist('a') ['1', '2'] >>> q['a'] # returns the last ['2']
相似標準字典的items() 方法,可是它使用的是和__getitem__ 同樣返回最新的值的邏輯。例如:
>>> q = QueryDict('a=1&a=2&a=3') >>> q.items() [('a', '3')]
相似標準字典的iteritems() 方法。相似QueryDict.items(),它使用的是和QueryDict.__getitem__() 同樣的返回最新的值的邏輯。
相似QueryDict.iteritems(),只是它將字典中的每一個成員做爲列表。
相似標準字典的values() 方法,可是它使用的是和__getitem__ 同樣返回最新的值的邏輯。例如:
>>> q = QueryDict('a=1&a=2&a=3') >>> q.values() ['3']
相似QueryDict.values(),只是它是一個迭代器。
另外,QueryDict 具備如下方法︰
返回對象的副本,使用Python 標準庫中的copy.deepcopy()。此副本是可變的即便原始對象是不可變的。
以Python 列表形式返回所請求的鍵的數據。若是鍵不存在而且沒有提供默認值,則返回空列表。它保證返回的是某種類型的列表,除非默認值不是列表。
設置給定的鍵爲list_(與__setitem__() 不一樣)。
將項追加到內部與鍵相關聯的列表中。
相似setdefault,除了它接受一個列表而不是單個值。
相似items,只是它將字典中的每一個成員做爲列表。例如:
>>> q = QueryDict('a=1&a=2&a=3') >>> q.lists() [('a', ['1', '2', '3'])]
返回給定鍵的值的列表,並從字典中移除它們。若是鍵不存在,將引起KeyError。例如 ︰
>>> q = QueryDict('a=1&a=2&a=3', mutable=True) >>> q.pop('a') ['1', '2', '3']
刪除字典任意一個成員(由於沒有順序的概念),並返回二值元組,包含鍵和鍵的全部值的列表。在一個空的字典上調用時將引起KeyError。例如 ︰
>>> q = QueryDict('a=1&a=2&a=3', mutable=True) >>> q.popitem() ('a', ['1', '2', '3'])
返回QueryDict 的dict 表示形式。對於QueryDict 中的每一個(key, list)對 ,dict 將有(key, item) 對,其中item 是列表中的一個元素,使用與QueryDict.__getitem__()相同的邏輯:
>>> q = QueryDict('a=1&a=3&a=5') >>> q.dict() {'a': '5'}
在查詢字符串格式返回數據的字符串形式。示例︰
>>> q = QueryDict('a=2&b=3&b=5') >>> q.urlencode() 'a=2&b=3&b=5'
可選地,urlencode 能夠傳遞不須要編碼的字符。例如︰
>>> q = QueryDict(mutable=True) >>> q['next'] = '/a&b/' >>> q.urlencode(safe='/') 'next=/a%26b/'
class HttpResponse
與由Django自動建立的HttpRequest 對象相比,HttpResponse 對象由程序員建立.你建立的每一個視圖負責初始化實例,填充並返回一個 HttpResponse.
HttpResponse 類是在django.http模塊中定義的。
用法
傳遞字符串
典型的應用是傳遞一個字符串做爲頁面的內容到HttpResponse 構造函數:
>>> from django.http import HttpResponse >>> response = HttpResponse("Here's the text of the Web page.") >>> response = HttpResponse("Text only, please.", content_type="text/plain")
若是你想增量增長內容,你能夠將response 看作一個類文件對象
>>> response = HttpResponse() >>> response.write("<p>Here's the text of the Web page.</p>") >>> response.write("<p>Here's another paragraph.</p>")
傳遞迭代器
最後你能夠傳遞給HttpResponse 一個迭代器而不是字符串. HttpResponse 將當即處理這個迭代器, 把它的內容存成字符串,並丟棄它
若是你須要從迭代器到客戶端的數據數據流的形式響應, 你必須用StreamingHttpResponse 類代替;.
配置 header fields
把它看成一個相似字典的結構,從你的response中設置和移除一個header field。
>>> response = HttpResponse() >>> response['Age'] = 120 >>> del response['Age']
注意!與字典不一樣的是,若是要刪除的header field不存在,del不會拋出KeyError異常。
HTTP header fields 不能包含換行。當咱們嘗試讓header field包含一個換行符(CR 或者 LF),那麼將會拋出一個BadHeaderError異常。
告訴瀏覽器以文件附件的形式處理服務器的響應
讓瀏覽器以文件附件的形式處理響應, 須要聲明 content_type 類型 和設置 Content-Disposition 頭信息. 例如,下面是 如何給瀏覽器返回一個微軟電子表格:
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel') >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'
There’s nothing Django-specific about the Content-Disposition header, but it’s easy to forget the syntax, so we’ve included it here.
屬性
一個用來代替content的字節字符串,若是必要,則從一個Unicode對象編碼而來。
New in Django 1.8.一個字符串,用來表示response將會被編碼的字符集。若是沒有在HttpResponse實例化的時候給定這個字符集,那麼將會從content_type 中解析出來。而且當這種解析成功的時候,DEFAULT_CHARSET選項將會被使用。
響應(response)的HTTP 響應狀態碼
The HTTP reason phrase for the response.
這個選項老是False。
因爲這個屬性的存在,使得中間件(middleware)可以卻別對待流式response和常規response。
HttpResponse.closed
New in Django 1.8.若是respose已經關閉則返回True
方法
使用頁面的內容(content)和content-type來實例化一個HttpResponse對象。
content 應該是一個迭代器或者字符串。若是它是一個迭代器,那麼他應該返回的是一串字符串,而且這些字符串鏈接起來造成response的內容(content)。若是不是迭代器或者字符串,那麼在其被接收的時候將轉換成字符串。
content_type is the MIME type optionally completed by a character set encoding and被用來填充 HTTP Content-Type響應頭部. 若是沒有設定, 會從 DEFAULT_CONTENT_TYPE 和 DEFAULT_CHARSET 設定中提取, 做爲默認值: 「text/html; charset=utf-8」.
status 是 HTTP 響應狀態碼 。
reason 是HTTP響應短語 若是沒有指定, 則使用默認響應短語.
charset 在response中被編碼的字符集。若是沒有給定,將會從 content_type中提取, 若是提取不成功, 那麼 DEFAULT_CHARSET 的設定將被使用.
由給定的首部名稱和值設定相應的報文首部。 header 和 value 都應該是字符串類型。
根據給定的首部名稱來刪除報文中的首部。若是對應的首部不存在將沉默地(不引起異常)失敗。不區分大小寫。
根據首部名稱返回其值。不區分大小寫。
經過檢查首部中是否有給定的首部名稱(不區分大小寫),來返回True 或 False 。
New in Django 1.8.設置一個首部,除非該首部 header 已經存在了。
設置一個Cookie。參數與Python 標準庫中的Morsel Cookie 對象相同。
max_age 以秒爲單位,若是Cookie 只應該持續客戶端瀏覽器的會話時長則應該爲None(默認值)。若是沒有指定expires,則會經過計算獲得。
expires 應該是一個 UTC "Wdy, DD-Mon-YY HH:MM:SS GMT" 格式的字符串,或者一個datetime.datetime 對象。若是expires 是一個datetime 對象,則max_age 會經過計算獲得。
若是你想設置一個跨域的Cookie,請使用domain 參數。例如,domain=".lawrence.com" 將設置一個www.lawrence.com、blogs.lawrence.com 和calendars.lawrence.com 均可讀的Cookie。不然,Cookie 將只能被設置它的域讀取。
若是你想阻止客服端的JavaScript 訪問Cookie,能夠設置httponly=True。
HTTPOnly 是包含在HTTP 響應頭部Set-Cookie 中的一個標記。它不是RFC 2109 中Cookie 的標準,也並無被全部的瀏覽器支持。可是,若是使用,它是一種下降客戶端腳本訪問受保護的Cookie 數據風險的有用的方法。
警告
RFC 2109 和RFC 6265 都聲明客戶端至少應該支持4096 個字節的Cookie。對於許多瀏覽器,這也是最大的大小。若是視圖存儲大於4096 個字節的Cookie,Django 不會引起異常,可是瀏覽器將不能正確設置Cookie。
與set_cookie() 相似,可是在設置以前將用密鑰簽名。一般與HttpRequest.get_signed_cookie() 一塊兒使用。你可使用可選的salt 參考來增長密鑰強度,但須要記住將它傳遞給對應的HttpRequest.get_signed_cookie() 調用。
刪除指定的key 的Cookie。若是key 不存在則什麼也不發生。
因爲Cookie 的工做方式,path 和domain 應該與set_cookie() 中使用的值相同 —— 不然Cookie 不會刪掉。
寫入內容到response
刷新response緩存
Django包含了一系列的HttpResponse衍生類(子類),用來處理不一樣類型的HTTP 響應(response)。與 HttpResponse相同, 這些衍生類(子類)存在於django.http之中。
構造函數的第一個參數是必要的 — 用來重定向的地址。這些可以是徹底特定的URL地址(好比,'http://www.yahoo.com/search/'),或者是一個不包含域名的絕對路徑地址(例如, '/search/')。關於構造函數的其餘參數,能夠參見 HttpResponse。注意!這個響應會返回一個302的HTTP狀態碼。
url
這個只讀屬性,表明響應將會重定向的URL地址(至關於Location response hader)。
與HttpResponseRedirect同樣,可是它會返回一個永久的重定向(HTTP狀態碼301)而不是一個「found」重定向(狀態碼302)。
構造函數不會有任何的參數,而且不該該向這個響應(response)中加入內容(content)。Use this to designate that a page hasn’t been modified since the user’s last request (status code 304).
與HttpResponse的行爲相似,可是使用了一個400的狀態碼。
與HttpResponse的行爲相似,可是使用的404狀態碼。
與HttpResponse的行爲相似,可是使用的403狀態碼。
與HttpResponse的行爲相似,可是使用的405狀態碼。 構造函數的第一個參數是必須的:一個容許使用的方法構成的列表(例如,['GET', 'POST'])。
與HttpResponse的行爲相似,可是使用的410狀態碼。
與HttpResponse的行爲相似,可是使用的500狀態碼。
New in Django 1.7.
HttpResponse 的一個子類,用戶幫助建立JSON 編碼的響應。它從父類繼承大部分行爲,並具備如下不一樣點:
它的默認Content-Type 頭部設置爲application/json。
它的第一個參數data,應該爲一個dict 實例。若是safe 參數設置爲False,它能夠是任何可JSON 序列化的對象。
encoder,默認爲 django.core.serializers.json.DjangoJSONEncoder,用於序列化data。
布爾參數safe 默認爲True。若是設置爲False,能夠傳遞任何對象進行序列化(不然,只容許dict 實例)。若是safe 爲True,而第一個參數傳遞的不是dict 對象,將拋出一個TypeError。
用法
典型的用法以下:
>>> from django.http import JsonResponse >>> response = JsonResponse({'foo': 'bar'}) >>> response.content '{"foo": "bar"}'
序列化非字典對象
若要序列化非dict 對象,你必須設置safe 參數爲False:
>>> response = JsonResponse([1, 2, 3], safe=False)
若是不傳遞safe=False,將拋出一個TypeError。
警告
在EcmaScript 第5版以前,這可能會使JavaScript Array 構造函數崩潰。出於這個緣由,Django 默認不容許傳遞非字典對象給JsonResponse 構造函數。然而,現代的大部分瀏覽器都已經實現EcmaScript 5,它刪除了這種攻擊性的數組。因此能夠不用關注這個安全預防措施。
修改默認的JSON 編碼器
若是你須要使用不一樣的JSON 編碼器類,你能夠傳遞encoder 參數給構造函數:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
class StreamingHttpResponse
StreamingHttpResponse類被用來從Django流式化一個響應(response)到瀏覽器。若是生成響應太長或者是有使用太多的內存,你可能會想要這樣作。例如,它對於生成大型CSV文件很是有用。
基於性能的考慮
Django是爲了那些短時間的請求(request)設計的。流式響應將會爲整個響應期協同工做進程。這可能致使性能變差。
總的來講,你須要將代價高的任務移除請求—響應的循環,而不是求助於流式響應。
StreamingHttpResponse 不是 HttpResponse的衍生類(子類),由於它實現了徹底不一樣的應用程序接口(API)。儘管如此,除了如下的幾個明顯不一樣的地方,其餘幾乎徹底相同:
屬性
一個表示內容(content)的字符串的迭代器
相應狀態碼
The HTTP reason phrase for the response.
這個選項老是 True.
FileResponse是StreamingHttpResponse的衍生類(子類),爲二進制文件作了優化。若是 wsgi server 來提供,則使用了 wsgi.file_wrapper ,不然將會流式化一個文件爲一些小塊。
FileResponse 須要經過二進制模式打開文件,以下:
>>> from django.http import FileResponse >>> response = FileResponse(open('myfile.png', 'rb'))