回顧 HTTP 協議的通訊核心,無非就是請求報文和響應報文之間的交互。而請求報文由客戶端生成,也就是用戶的瀏覽器;響應報文則由服務器生成,做爲web應用的開發者,大多數工做就是構造一個合適的響應報文。在 django 中,請求報文已經被封裝成了 HttpRequest 對象,該對象的建立是自動的,且會傳遞給視圖函數做爲第一個參數。而 HttpResponse 對象則須要 web 開發者本身建立,通常在視圖函數中 return 回去。下面咱們就來看看 HttpResponse 對象的各類細節。html
首先,這個對象由 HttpResponse 類建立,這個類位於 django.http 模塊中,因此在使用的時候還先從模塊中導入這個類。python
例如:web
from django.http import HttpResponse
而後,咱們須要知道傳遞什麼參數,這個時候先看看其構造函數是怎麼樣的。django
HttpResponse.__init__(content='', content_type=None, status=200, reason=None, charset=None) json
content:能夠是一個迭代器或字符串。若是是一個迭代器,HttpResponse 將當即處理這個迭代器, 把它的內容轉成字符串,並丟棄這個迭代器。若是你須要從迭代器到客戶端的數據響應以數據流的形式, 你必須用 StreamingHttpResponse 類代替;若是是一個字符串(迭代器處理後的或手動傳入的),那麼這個字符串將做爲相應報文的主體內容,也就是說若是是一個 http 文檔,那麼這個文檔將會放入響應報文的主體中,最後在瀏覽器中顯示,這也是最爲經常使用的方式之一。數組
content_type:用於指定 MIME 類型和編碼,例如:「text/html; charset=utf-8」。客戶端須要知道主體是什麼類型的資源,才能調用相應的插件或內置的程序去處理。若是不傳入,也就是爲 None 時,將使用 DEFAULT_CONTENT_TYPE 的值來指定 MIME 類型,這個值默認爲:'text/html';使用 DEFAULT_CHARSET 的值來指定文件編碼,默認爲:'utf-8'。瀏覽器
status:響應狀態碼,200表明成功,通常不須要改變,除非有特殊要求。緩存
reason:緣由短語,也就是 200 ok 中的 ‘ok’,由於客戶端是根據狀態碼來判斷響應是否成功的,因此 reason 的影響幾乎爲 0 ,只是對人的提醒而已。若是沒有指定, 則使用默認響應短語。也就是 200 就對應於 ok,404 就對應於 not found。安全
charset:在response中被編碼的字符集。若是沒有給定(也就是爲None),將會從 content_type 中提取,若是提取不成功, 那麼 DEFAULT_CHARSET 的設定將被使用。服務器
一樣的,咱們可使用相關的屬性去查看這些值:
HttpResponse.content :表示內容的字符串,對應於咱們傳入的 content 參數的值。
HttpResponse.charset :一個表示編碼的字符串,對應於 charset 參數,若是實例化的時候沒有給定,將從 content_type 中解析出來,若是解析失敗,將使用 DEFAULT_CHARSET 的值。
HttpResponse.status_code :表示響應的狀態碼。在 1.9 中除非 reason_phrase 屬性被顯式的設置,不然在構造函數外修改狀態碼時,也會修改 reason_phrase 屬性。也就是說,當咱們在建立實例的時候,並無設置 reason ,原來的狀態碼是 200 ,當咱們在構造器外修改這個屬性的時候,如修改爲 404,那麼 reason_phrase 屬性就變成對應的 not found。
HttpResponse.reason_phrase :表示響應的緣由短語,對應於 reason 參數。在1.9中 reason_phrase 再也不默認爲所有大寫字母。如今使用 HTTP 標準的默認緣由短語。除非顯式設置,reason_phrase 由status_code 的值的肯定。
HttpResponse.streaming :這個選項老是 False。由於這個屬性的存在,使得中間件(middleware)可以區別對待流式 response 和常規 response 。
HttpResponse.closed :若是響應已關閉,則是 True 的。
HttpResponse.__setitem__(header, value)
由給定的首部名稱和值設定相應的報文首部。 header 和 value 都應該是字符串類型。
HttpResponse.__delitem__(header)
根據給定的首部名稱來刪除報文中的首部。若是對應的首部不存在將沉默地(不引起異常)失敗。不區分大小寫。
HttpResponse.__getitem__(header)
根據首部名稱返回其值。不區分大小寫。
HttpResponse.has_header(header)
經過檢查首部中是否有給定的首部名稱(不區分大小寫),來返回 True 或 False 。
HttpResponse.setdefault(header, value)
設置一個首部,除非該首部 header 已經存在了。
另外,咱們還可使用類字典的方法來設置首部,例如:
>>> response = HttpResponse() >>> response['Age'] = 120 >>> del response['Age']
注意:當調用 del 去刪除的首部不存在時,會引起 KeyError
異常。
可是,當咱們設定 Cache-Control 首部和 Vary 首部時,推薦使用 patch_cache_control() 和 patch_vary_headers()方法,能夠從 django.utils.cache 中導入它們。由於這兩個首部一般有多個值,這些值都要逗號隔開。"patch" 方法能夠確保這些值,例如由中間件添加的值不會被改變。而字典形式添加的,同名鍵的不一樣值會發生衝突,只有最後一個值有效。
另外,雖然標準的 HTTP 報文中要求首部的每一行都要使用換行符隔開,可是 django 已經幫咱們作了這些,因此咱們不用重複的添加換行符了,不然會觸發 BadHeaderError 異常。
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
設置一個Cookie。參數與Python 標準庫中的 Morsel Cookie 對象相同。
key:鍵名,字符串形式。
value:對應的值,字符串形式。
max_age:cookie 過時的相對時間,單位是秒。若是爲None,則當瀏覽器關閉的時候過時。若是設置了 max_age 而沒有設置 expires,則 expires 將根據 max_age 的值計算出來。
expires:設置 cookie 過時的絕對時間。應該是一個 UTC "Wdy, DD-Mon-YY HH:MM:SS GMT" 格式的字符串,或者一個 datetime.datetime 對象。若是 expires 是一個datetime 對象,則 max_age 會經過計算獲得。
path:一個字符串,表示客戶端回送 cookie 的路徑,若是爲‘/’,則表示該域名下的因此路徑都將回送 cookie,若是是‘/blog/’;則在訪問‘/blog/abc’或者‘/blog/def’等,全部包含該前綴的路徑時,客戶端都會回送 cookie。
domain:cookie有效的域。例如,其值爲‘.scolia.com’時,那麼在訪問 www.scolia.com 或者 test.scolia.com 之類的時,都會回送 cookie ,固然一般會和 path 配合在一塊兒使用。根據 HTTP 協議的要求,這個值必要要兩到三個句點,從而防止出現 ‘.com’、‘.edu’、‘va.us’等形式的域名。當域爲高層域時,只要兩個句點就能夠了,而高層域包括:.com、.edu、.net、.org、.gov、.mil、.int、.biz、.info、.name、 .museum、.coop、.aero、和.pro。其餘的域則須要至少三個。
secure:當其爲 True 時,表示只要在 https 鏈接的狀況下才會回送cookie
httponly:當其爲 True 時,JavaScript 等就不能訪問對應的cookie了。固然這個標記並非cookie標準中的,但目前市面上經常使用的瀏覽器都支持。靈活使用能夠提供數據的安全性。
注意:
RFC 2109 和RFC 6265 都聲明客戶端至少應該支持 4096 個字節的Cookie。對於許多瀏覽器,這也是最大的大小。若是視圖存儲大於 4096 個字節的 Cookie,Django 不會引起異常,可是瀏覽器將不能正確設置 Cookie。
HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)
與 set_cookie() 相似,可是在設置以前將用密鑰簽名,也就是常說的加鹽處理。一般與 HttpRequest.get_signed_cookie() 一塊兒使用。你可使用可選的 salt 參數來增長密鑰強度,但須要記住在調用 HttpRequest.get_signed_cookie() 時,也要把使用的 salt 參數傳入,用於解密。
HttpResponse.delete_cookie(key, path='/', domain=None)
在cookie中刪除指定的 key 及其對應的 value。若是 key 不存在則什麼也不發生,也就是不會引起異常。
因爲 Cookie 的工做方式,path 和 domain 應該與 set_cookie() 中使用的值相同 —— 不然 Cookie 不會刪掉。
HttpResponse.write(content)
將 content 寫到報文的主體中,這使得 HttpResponse
的實例相似於文件對象。
相似的還有:
HttpResponse.flush() :將緩存區的內容寫入到報文中
HttpResponse.tell() :移動文件中的操做指針
HttpResponse.getvalue()
從 HttpResponse.
content 中返回其值。這使 HttpResponse 的實例相似於數據流對象。
HttpResponse.writable()
老是 True,表示其是可寫的。這使 HttpResponse 的實例相似於數據流對象。
HttpResponse.writelines(lines)
在內容中寫入一行。不添加行分隔符。這使 HttpResponse 的實例相似於數據流對象。
Django包含了一系列的HttpResponse衍生類(子類),用來處理不一樣類型的HTTP 響應(response)。與 HttpResponse 相同, 這些衍生類(子類)存在於 django.http 之中。
class HttpResponseRedirect
構造函數的第一個參數是必要的 — 用來重定向的地址。這些可以是徹底特定的URL地址(好比,'http://www.yahoo.com/search/'),或者是一個不包含域名的絕對路徑地址(例如, '/search/')。關於構造函數的其餘參數,能夠參見 HttpResponse。注意!這個響應會返回一個302的HTTP狀態碼。
url:一個只讀屬性,表示表明響應將會重定向的URL地址(至關於Location 首部信息)。
class HttpResponsePermanentRedirect
與 HttpResponseRedirect 同樣,可是它會返回一個永久的重定向(HTTP狀態碼301)而不是一個「found」重定向(狀態碼302)。
class HttpResponseNotModified
構造函數不會有任何的參數,而且不該該向這個響應(response)中加入內容(content)。使用這個意味着資源在用戶最後一次請求以後,沒有修改過(狀態碼304)。
class HttpResponseBadRequest
與HttpResponse的行爲相似,可是使用了一個400的狀態碼。表示一個錯誤的請求。
class HttpResponseNotFound
與HttpResponse的行爲相似,可是使用了一個404的狀態碼。表示資源沒有找到。
class HttpResponseForbidden
與HttpResponse的行爲相似,可是使用了一個403的狀態碼。表示用戶無權訪問。
class HttpResponseNotAllowed
與HttpResponse的行爲相似,可是使用了一個405的狀態碼。表示請求的方法不被容許。 構造函數的第一個參數是必須的:一個容許使用的方法構成的列表(例如,['GET', 'POST'])。也就是說不在列表中的方法就是不被運行的方法。
class HttpResponseGone
與HttpResponse的行爲相似,可是使用了一個410的狀態碼。表示服務器曾經擁有過此資源。主要是在 web 站點進行維護的時候,通知客戶端。
class HttpResponseServerError
與HttpResponse的行爲相似,可是使用了一個500的狀態碼。表示服務器內部錯誤。
注意:若是一個自定義的 HttpResponse 的子類實現了 render 方法,那麼 django 會將其看成一個 SimpleTemplateResponse。 render 方法必須返回一個有效的響應對象。
json是目前經常使用的一種數據格式,有時候咱們須要返回一個json格式的數據,而 JsonResponse 提供了一個快捷的方法。
它是 HttpResponse 的一個子類,用來幫助用戶建立JSON 編碼的響應。它從父類繼承大部分行爲,下面看起構造函數:
class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)
data:應該傳遞一個標準的 python 字典給它,它將其轉換成 json 格式的數據。
encoder:默認爲 django.core.serializers.json.DjangoJSONEncoder,用於序列化data。關於這個序列化的更多信息參見JSON 序列化。
safe : 默認爲True。若是設置爲False,能夠傳遞任何對象進行序列化(不然,只容許dict 實例)。若是safe 爲True,而第一個參數傳遞的不是dict 對象,將拋出一個TypeError。
另外:它的默認 Content-Type 頭部設置爲application/json。
json_dumps_params:在1.9版本中新增,能夠傳遞一個python標準的 json 庫中,json.dump() 方法處理後的對象給它,用於生成一個響應。
典型的用法以下:
>>> 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 編碼器類,你能夠傳遞encoder 參數給構造函數:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
class StreamingHttpResponse
StreamingHttpResponse類被用來從Django流式化一個響應(response)到瀏覽器。當生產的響應太長或者佔用太多的內存的時候,你可能會使用到它。例如,它對於生成大型CSV文件很是有用。
性能方面的考慮:
django是爲了短連接而設計的,也就是說每次響應完畢以後都會斷開鏈接。流式響應將會爲整個響應期協同工做進程。這可能致使性能變差。
總的來講,你須要將代價高的任務移除 請求—響應 的循環,而不是求助於流式響應。
StreamingHttpResponse 不是 HttpResponse 的衍生類(子類),由於它實現了徹底不一樣的應用程序接口(API)。儘管如此,除了如下的幾個明顯不一樣的地方,其餘幾乎徹底相同:
StreamingHttpResponse
應該只在下面的狀況下使用:請求是獨立的,而且整個內容是不能重複的,在發生給客戶端以前。由於其內容(content)是不能訪問的,因此不少中間件是沒法正常工做的。例如:ETag 和 Content- Length 首部就不能在流式相應中生成。
屬性:
StreamingHttpResponse.streaming_content
一個迭代器,包含內容字符串。
StreamingHttpResponse.status_code
響應的狀態碼
StreamingHttpResponse.reason_phrase
響應的緣由短語
StreamingHttpResponse.streaming
老是True,表示其是一個流式響應。
FileResponse
class FileResponse
FileResponse是StreamingHttpResponse的衍生類(子類),爲二進制文件作了優化。若是 wsgi server 來提供,則使用了wsgi.file_wrapper ,不然將會流式化一個文件爲一些小塊。
FileResponse 須要經過二進制模式打開文件,以下:
>>> from django.http import FileResponse >>> response = FileResponse(open('myfile.png', 'rb'))