Django的HttpRequest和HttpResponse對(duì)象詳解
本文研究的主要是Django的HttpRequest和HttpResponse對(duì)象的相關(guān)內(nèi)容,具體如下。
請(qǐng)求一張頁(yè)面時(shí),Django把請(qǐng)求的metadata數(shù)據(jù)包裝成一個(gè)HttpRequest對(duì)象,然后Django加載合適的view方法,把這個(gè)HttpRequest 對(duì)象作為第一個(gè)參數(shù)傳給view方法。任何view方法都應(yīng)該返回一個(gè)HttpResponse對(duì)象。
我們?cè)诒緯写罅渴褂眠@兩個(gè)對(duì)象;本附錄詳細(xì)解釋HttpRequest和HttpResponse對(duì)象。
HttpRequest
HttpRequest代表一個(gè)來自u(píng)esr-agent的HTTP請(qǐng)求。
大多重要的請(qǐng)求信息都是作為HttpRequest 對(duì)象的屬性出現(xiàn)(see Table H-1). 除了session外,其他所有屬性都是只讀的。
Table H-1. HttpRequest對(duì)象的屬性
Attribute |
Description |
path |
請(qǐng)求頁(yè)面的全路徑,不包括域名—例如, "/music/bands/the_beatles/"。 |
method |
請(qǐng)求中使用的HTTP方法的字符串表示。全大寫表示。例如: if request.method == 'GET': |
GET |
包含所有HTTP GET參數(shù)的類字典對(duì)象。參見QueryDict 文檔。 |
POST |
包含所有HTTP POST參數(shù)的類字典對(duì)象。參見QueryDict 文檔。 服務(wù)器收到空的POST請(qǐng)求的情況也是有可能發(fā)生的。也就是說,表單form通過HTTP POST方法提交請(qǐng)求,但是表單中可以沒有數(shù)據(jù)。因此,不能使用語(yǔ)句if request.POST來判斷是否使用HTTP POST方法;應(yīng)該使用if request.method == "POST" (參見本表的method屬性)。 注意: POST不包括file-upload信息。參見FILES屬性。 |
REQUEST |
為了方便,該屬性是POST和GET屬性的集合體,但是有特殊性,先查找POST屬性,然后再查找GET屬性。借鑒PHP's $_REQUEST。 例如,如果GET = {"name": "john"} 和POST = {"age": '34'},則 REQUEST["name"] 的值是"john", REQUEST["age"]的值是"34". 強(qiáng)烈建議使用GET and POST,因?yàn)檫@兩個(gè)屬性更加顯式化,寫出的代碼也更易理解。 |
COOKIES |
包含所有cookies的標(biāo)準(zhǔn)Python字典對(duì)象。Keys和values都是字符串。參見第12章,有關(guān)于cookies更詳細(xì)的講解。 |
FILES |
包含所有上傳文件的類字典對(duì)象。FILES中的每個(gè)Key都是<input type="file" name="" />標(biāo)簽中name屬性的值. FILES中的每個(gè)value 同時(shí)也是一個(gè)標(biāo)準(zhǔn)Python字典對(duì)象,包含下面三個(gè)Keys:
注意:只有在請(qǐng)求方法是POST,并且請(qǐng)求頁(yè)面中<form>有enctype="multipart/form-data"屬性時(shí)FILES才擁有數(shù)據(jù)。否則,F(xiàn)ILES 是一個(gè)空字典。 |
META |
包含所有可用HTTP頭部信息的字典。 例如:
META 中這些頭加上前綴HTTP_最為Key, 例如:
|
user |
是一個(gè)django.contrib.auth.models.User 對(duì)象,代表當(dāng)前登錄的用戶。如果訪問用戶當(dāng)前沒有登錄,user將被初始化為django.contrib.auth.models.AnonymousUser的實(shí)例。你可以通過user的is_authenticated()方法來辨別用戶是否登錄: if request.user.is_authenticated(): 只有激活Django中的AuthenticationMiddleware時(shí)該屬性才可用 關(guān)于認(rèn)證和用戶的更詳細(xì)講解,參見第12章。 |
session |
唯一可讀寫的屬性,代表當(dāng)前會(huì)話的字典對(duì)象。只有激活Django中的session支持時(shí)該屬性才可用。 參見第12章。 |
raw_post_data |
原始HTTP POST數(shù)據(jù),未解析過。 高級(jí)處理時(shí)會(huì)有用處。 |
Request對(duì)象也有一些有用的方法,見Table H-2:
Table H-2. HttpRequest Methods |
|
Method |
Description |
__getitem__(key) |
返回GET/POST的鍵值,先取POST,后取GET。如果鍵不存在拋出 KeyError。 這是我們可以使用字典語(yǔ)法訪問HttpRequest對(duì)象。 例如,request["foo"]等同于先request.POST["foo"] 然后 request.GET["foo"]的操作。 |
has_key() |
檢查request.GET or request.POST中是否包含參數(shù)指定的Key。 |
get_full_path() |
返回包含查詢字符串的請(qǐng)求路徑。例如, "/music/bands/the_beatles/?print=true" |
is_secure() |
如果請(qǐng)求是安全的,返回True,就是說,發(fā)出的是HTTPS請(qǐng)求。 |
QueryDict對(duì)象
在HttpRequest對(duì)象中, GET和POST屬性是django.http.QueryDict類的實(shí)例。 QueryDict類似字典的自定義類,用來處理單鍵對(duì)應(yīng)多值的情況。因?yàn)橐恍〩TML form元素,例如,<selectmultiple="multiple">, 就會(huì)傳多個(gè)值給單個(gè)鍵。
QueryDict對(duì)象是immutable(不可更改的),除非創(chuàng)建它們的copy()。這意味著我們不能直接改變r(jià)equest.POST and request.GET的屬性。
QueryDict實(shí)現(xiàn)所有標(biāo)準(zhǔn)的字典方法。還包括一些特有的方法,見Table H-3.
Table H-3. How QueryDicts Differ from Standard Dictionaries. |
|
Method |
Differences from Standard dict Implementation |
__getitem__ |
和標(biāo)準(zhǔn)字典的處理有一點(diǎn)不同,就是,如果Key對(duì)應(yīng)多個(gè)Value,__getitem__()返回最后一個(gè)value。 |
__setitem__ |
設(shè)置參數(shù)指定key的value列表(一個(gè)Python list)。注意:它只能在一個(gè)mutable QueryDict 對(duì)象上被調(diào)用(就是通過copy()產(chǎn)生的一個(gè)QueryDict對(duì)象的拷貝). |
get() |
如果key對(duì)應(yīng)多個(gè)value,get()返回最后一個(gè)value。 |
update() |
參數(shù)可以是QueryDict,也可以是標(biāo)準(zhǔn)字典。和標(biāo)準(zhǔn)字典的update方法不同,該方法添加字典 items,而不是替換它們: >>> q = QueryDict('a=1') ['1', '2'] |
items() |
和標(biāo)準(zhǔn)字典的items()方法有一點(diǎn)不同,該方法使用單值邏輯的__getitem__(): >>> q = QueryDict('a=1&a=2&a=3') |
values() |
和標(biāo)準(zhǔn)字典的values()方法有一點(diǎn)不同,該方法使用單值邏輯的__getitem__(): |
此外, QueryDict也有一些方法,見Table H-4.
H-4. 額外的 (非字典的) QueryDict 方法 |
|
Method |
Description |
copy() |
返回對(duì)象的拷貝,內(nèi)部實(shí)現(xiàn)是用Python標(biāo)準(zhǔn)庫(kù)的copy.deepcopy()。該拷貝是mutable(可更改的) — 就是說,可以更改該拷貝的值。 |
getlist(key) |
返回和參數(shù)key對(duì)應(yīng)的所有值,作為一個(gè)Python list返回。如果key不存在,則返回空l(shuí)ist。 It's guaranteed to return a list of some sort.. |
setlist(key,list_) |
設(shè)置key的值為list_ (unlike __setitem__()). |
appendlist(key,item) |
添加item到和key關(guān)聯(lián)的內(nèi)部list. |
setlistdefault(key,list) |
和setdefault有一點(diǎn)不同,它接受list而不是單個(gè)value作為參數(shù)。 |
lists() |
和items()有一點(diǎn)不同, 它會(huì)返回key的所有值,作為一個(gè)list, 例如: >>> q = QueryDict('a=1&a=2&a=3') |
urlencode() |
返回一個(gè)以查詢字符串格式進(jìn)行格式化后的字符串(e.g., "a=2&b=3&b=5"). |
A Complete Example
例如, 下面是一個(gè)HTML form:
<span style="font-size:12px;"><form action="/foo/bar/" method="post"> <input type="text" name="your_name" /> <select multiple="multiple" name="bands"> <option value="beatles">The Beatles</option> <option value="who">The Who</option> <option value="zombies">The Zombies</option> </select> <input type="submit" /> </form></span>
如果用戶在your_name域中輸入"JohnSmith",同時(shí)在多選框中選擇了“The Beatles”和“The Zombies”,下面是Django請(qǐng)求對(duì)象的內(nèi)容:
>>> request.GET{} >>> request.POST {'your_name': ['John Smith'], 'bands': ['beatles', 'zombies']} >>> request.POST['your_name'] 'John Smith' >>> request.POST['bands'] 'zombies' >>> request.POST.getlist('bands') ['beatles', 'zombies'] >>> request.POST.get('your_name', 'Adrian') 'John Smith' >>> request.POST.get('nonexistent_field', 'Nowhere Man') 'Nowhere Man'
HttpResponse
對(duì)于HttpRequest 對(duì)象來說,是由Django自動(dòng)創(chuàng)建, 但是,HttpResponse對(duì)象就必須我們自己創(chuàng)建。每個(gè)View方法必須返回一個(gè)HttpResponse對(duì)象。
HttpResponse類在django.http.HttpResponse。
構(gòu)造HttpResponses
一般地, 你可以通過給HttpResponse的構(gòu)造函數(shù)傳遞字符串表示的頁(yè)面內(nèi)容來構(gòu)造HttpResponse對(duì)象:
>>> response = HttpResponse("Here's the text of the Web page.") >>> response = HttpResponse("Text only, please.", mimetype="text/plain")
但是如果想要增量添加內(nèi)容, 你可以把response當(dāng)作filelike對(duì)象使用:
>>> response = HttpResponse() >>> response.write("<p>Here's the text of the Web page.</p>") >>> response.write("<p>Here's another paragraph.</p>")
也可以給HttpResponse傳遞一個(gè)iterator作為參數(shù),而不用傳遞硬編碼字符串。 如果你使用這種技術(shù), 下面是需要注意的一些事項(xiàng):
· iterator應(yīng)該返回字符串.
· 如果HttpResponse使用iterator進(jìn)行初始化,就不能把HttpResponse實(shí)例作為filelike 對(duì)象使用。這樣做將會(huì)拋出異常。
最后,再說明一下,HttpResponse實(shí)現(xiàn)了write()方法, 可以在任何需要filelike對(duì)象的地方使用HttpResponse對(duì)象。參見第11章,有一些例子。
設(shè)置Headers
你可以使用字典語(yǔ)法添加,刪除headers:
>>> response = HttpResponse() >>> response['X-DJANGO'] = "It's the best." >>> del response['X-PHP'] >>> response['X-DJANGO'] "It's the best."
你也可以使用has_header(header)方法檢測(cè)某個(gè)header是否存在。
不要手動(dòng)設(shè)置Cookie headers;具體的做法,參見第12章,有關(guān)于怎樣在Django中處理cookies的詳細(xì)講解。
HttpResponse子類
Django包含很多HttpResponse子類,用來處理不同的HTTP響應(yīng)類型(見Table H-5). 和HttpResponse一樣, 這些子類在django.http中.
Table H-5. HttpResponse Subclasses |
|
Class |
Description |
HttpResponseRedirect |
構(gòu)造函數(shù)接受單個(gè)參數(shù):重定向到的URL。可以是全URL (e.g., 'http://search.yahoo.com/')或者相對(duì)URL(e.g., '/search/'). 注意:這將返回HTTP狀態(tài)碼302。 |
HttpResponsePermanentRedirect |
同HttpResponseRedirect一樣,但是返回永久重定向(HTTP 狀態(tài)碼 301)。 |
HttpResponseNotModified |
構(gòu)造函數(shù)不需要參數(shù)。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. 它需要一個(gè)必須的參數(shù):一個(gè)允許的方法的list (e.g., ['GET','POST']). |
HttpResponseGone |
返回410 status code. |
HttpResponseServerError |
返回500 status code. |
當(dāng)然,你也可以自己定義不包含在上表中的HttpResponse子類。
返回Errors
在Django中返回HTTP錯(cuò)誤碼是很容易的。上面介紹了HttpResponseNotFound, HttpResponseForbidden, HttpResponseServerError等一些子類。View方法中返回這些子類的實(shí)例就OK了,例如:
def my_view(request): # ... if foo: return HttpResponseNotFound('<h1>Page not found</h1>') else: return HttpResponse('<h1>Page was found</h1>')
當(dāng)返回HttpResponseNotFound時(shí),你需要定義錯(cuò)誤頁(yè)面的HTML:
return HttpResponseNotFound('<h1>Page not found</h1>')
因?yàn)?04錯(cuò)誤是最常使用的HTTP錯(cuò)誤, 有一個(gè)更方便的方法處理它。
為了方便,而且整個(gè)站點(diǎn)有一致的404錯(cuò)誤頁(yè)面也是友好的,Django提供一個(gè)Http404異常類。如果在一個(gè)View方法中拋出Http404,Django將會(huì)捕獲它并且返回標(biāo)準(zhǔn)錯(cuò)誤頁(yè)面,同時(shí)返回錯(cuò)誤碼404。
from django.http import Http404 def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render_to_response('polls/detail.html', {'poll': p})
為了使用Http404異常, 你需要?jiǎng)?chuàng)建一個(gè)模板文件。當(dāng)異常拋出時(shí),就會(huì)顯示該模板文件。該模板文件的文件名是404.html,在模板根目錄下創(chuàng)建。
自定義404 (Not Found) View方法
當(dāng)拋出Http404異常時(shí), Django會(huì)加載一個(gè)特殊的view方法處理404錯(cuò)誤。默認(rèn)地, 它是django.views.defaults.page_not_found,負(fù)責(zé)加載和渲染404.html模板文件。
這意味著我們必須在模板根目錄定義404.html模板文件,該模板文件應(yīng)用于所有的404異常。
該page_not_found view方法應(yīng)該可以應(yīng)對(duì)幾乎99%的Web App,但是如果想要重載該view方法時(shí), 你可以在URLConf文件中指定handler404為自定義的404 errpr view方法, 像這樣:
from django.conf.urls.defaults import * urlpatterns = patterns('', ... ) handler404 = 'mysite.views.my_custom_404_view'
Django就是通過在URLConf文件中查找handler404來決定404 view方法的。默認(rèn)地, URLconfs包含下面一行代碼:
from django.conf.urls.defaults import *
在 django/conf/urls/defaults.py模塊中, handler404賦值為 'django.views.defaults.page_not_found'。
注意:
· 如果請(qǐng)求URL沒有和Django的URLConf文件中的任何一個(gè)正則表示式匹配,404 view方法就會(huì)被調(diào)用。
· 如果沒有定義自己的404 view — 使用默認(rèn)地404 view,你仍然有一個(gè)工作要做:在模板根目錄創(chuàng)建404.html模板文件。默認(rèn)地404 view將使用該模板處理所有404錯(cuò)誤。
· 如果 DEBUG設(shè)置為True (在setting模塊中),404 view方法不會(huì)被使用,取而代之的是,traceback信息。
自定義500 (Server Error) View方法
同樣地,當(dāng)view代碼發(fā)生運(yùn)行時(shí)錯(cuò)誤時(shí),Django也會(huì)產(chǎn)生特殊行為。如果view方法產(chǎn)生異常,Django將會(huì)調(diào)用默認(rèn)地view方法django.views.defaults.server_error, 該方法加載渲染500.html模板文件。
這意味著我們必須在模板根目錄定義500.html模板文件,該模板文件應(yīng)用于所有的服務(wù)器錯(cuò)誤。
該server_error view方法應(yīng)該可以應(yīng)對(duì)幾乎99%的Web App,但是如果想要重載該view方法時(shí), 你可以在URLConf文件中指定handler500為自定義的server error view方法, 像這樣:
from django.conf.urls.defaults import * urlpatterns = patterns('', ... ) handler500 = 'mysite.views.my_custom_error_view'
翻譯文章來源 (Django官網(wǎng)文檔):https://docs.djangoproject.com/en/1.9/ref/request-response/#django.http.HttpRequest
其中進(jìn)行了一些整理。
總結(jié)
以上就是本文關(guān)于Django的HttpRequest和HttpResponse對(duì)象詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
一文教你掌握Python中Lambda表達(dá)式的5種實(shí)用技巧
在Python編程的宇宙里,有一個(gè)強(qiáng)大而靈活的工具經(jīng)常被高效的程序員所利用——那就是Lambda表達(dá)式,下面就讓我們深入了解Lambda表達(dá)式的妙用吧2024-01-01Python 實(shí)現(xiàn)簡(jiǎn)單的shell sed替換功能(實(shí)例講解)
下面小編就為大家?guī)硪黄狿ython 實(shí)現(xiàn)簡(jiǎn)單的shell sed替換功能(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09使用Playwright進(jìn)行視覺回歸測(cè)試詳解
這篇文章主要介紹了使用Playwright進(jìn)行視覺回歸測(cè)試詳解,視覺回歸測(cè)試是一種軟件測(cè)試技術(shù),專注于檢測(cè)Web應(yīng)用程序或網(wǎng)站的用戶界面中的視覺變化和差異,需要的朋友可以參考下2023-08-08Python設(shè)計(jì)模式中單例模式的實(shí)現(xiàn)及在Tornado中的應(yīng)用
這篇文章主要介紹了Python設(shè)計(jì)模式中單例模式的實(shí)現(xiàn)及在Tornado中的應(yīng)用,講解了單例模式用于設(shè)計(jì)Tornado框架中的線程控制方面的相關(guān)問題,需要的朋友可以參考下2016-03-03Python修改Excel數(shù)據(jù)的實(shí)例代碼
Python修改Excel數(shù)據(jù)的方法。2013-11-11