Python Django 前后端数据交互 之 HttpRequest、HttpResponse、render、redirect
生活随笔
收集整理的這篇文章主要介紹了
Python Django 前后端数据交互 之 HttpRequest、HttpResponse、render、redirect
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在使用三神裝的時(shí)候,首先當(dāng)然是得要導(dǎo)入它們: from django.shortcuts import HttpResponse, render, redirect
HttpRequest.body??? #一個(gè)字節(jié)字符串,表示原始HTTP請(qǐng)求的正文
HttpRequest.path??? #一個(gè)字符串,表示請(qǐng)求的頁(yè)面的完整路徑,不包含域名
HttpRequest.methed?? #一個(gè)字符串,表示請(qǐng)求使用的HTTP方法,必須使用大寫(xiě)
HttpRequest.GET????? #一個(gè)類(lèi)似于字典的對(duì)象,包含HTTP GET的所有參數(shù)
HttpRequest.POST???? #一個(gè)包含所有給定的HTTP POST參數(shù)的類(lèi)字典對(duì)象,提供了包含表單數(shù)據(jù)的請(qǐng)求
HttpRequest.COOKIES??? #一個(gè)標(biāo)準(zhǔn)的python字典,包含所有cookie,鍵和值都為字符串
HttpRequest.FILES???? #一個(gè)類(lèi)似于字典的對(duì)象,包含所有的上傳文件
HttpRequest.META????? #一個(gè)標(biāo)準(zhǔn)的python字典,包含所有的HTTP頭部123456789
HttpRequest.get_full_path()#返回path,如果可以將加上查詢字符串
HttpRequest.read(size=None)
HttpRequest.readline()
HttpRequest.readlines()
HttpRequest.xreadlines()
HttpRequest.__iter__()
#這幾個(gè)方法實(shí)現(xiàn)類(lèi)文件的接口用于讀取HttpRequest.示例。這使得可以用流的方式讀#取進(jìn)來(lái)的請(qǐng)求,一個(gè)常見(jiàn)的用例是使用迭代解析器處理大型XML有效載荷, 而不是內(nèi)存#中構(gòu)造一個(gè)完整的XML樹(shù)。
其中的xxx為網(wǎng)址映射,在urlsl路由映射部分再做詳解。 # 接收請(qǐng)求數(shù)據(jù)返回字符串響應(yīng)
def index(request):
??? if request.method == "POST":
??????? username = request.POST.get("username", None)?? # 讀取post數(shù)據(jù),None為默認(rèn)值
??????? password = request.POST.get("password", None)?? # 讀取post數(shù)據(jù),None為默認(rèn)值
??? if request.method == "GET":
??????? username = request.GET.get("username", None)?? # 讀取get數(shù)據(jù)
??????? password = request.GET.get("password", None)? # 讀取get數(shù)據(jù)
??? ...123456789 在獲取數(shù)據(jù)時(shí),通常會(huì)提供一個(gè)默認(rèn)值,防止請(qǐng)求數(shù)據(jù)中沒(méi)有目標(biāo)屬性時(shí)觸發(fā)KeyError異常。 不僅如此,HttpRequest對(duì)象中包含了非常多的重要的信息和數(shù)據(jù),應(yīng)該熟練掌握它。 1)HttpRequest屬性 (1)、 HttpRequest.scheme
字符串類(lèi)型,表示請(qǐng)求的協(xié)議種類(lèi),’http’或’https’。 (2)、 HttpRequest.body
bytes類(lèi)型,表示原始HTTP請(qǐng)求的正文。它對(duì)于處理非HTML形式的數(shù)據(jù)非常有用:二進(jìn)制圖像、XML等。如果要處理常規(guī)的表單數(shù)據(jù),應(yīng)該使用HttpRequest.POST。還可以使用類(lèi)似讀寫(xiě)文件的方式從HttpRequest中讀取數(shù)據(jù),參見(jiàn)HttpRequest.read()。 (3)、 HttpRequest.path
字符串類(lèi)型,表示當(dāng)前請(qǐng)求頁(yè)面的完整路徑,但是不包括協(xié)議名和域名。例如:”/music/bands/the_beatles/”。這個(gè)屬性,常被用于我們進(jìn)行某項(xiàng)操作時(shí),如果不通過(guò),返回用戶先前瀏覽的頁(yè)面。非常有用! (4)、 HttpRequest.path_info
在某些Web服務(wù)器配置下,主機(jī)名后的URL部分被分成腳本前綴部分和路徑信息部分。path_info 屬性將始終包含路徑信息部分,不論使用的Web服務(wù)器是什么。使用它代替path可以讓代碼在測(cè)試和開(kāi)發(fā)環(huán)境中更容易地切換。
例如,如果應(yīng)用的WSGIScriptAlias設(shè)置為/minfo,那么HttpRequest.path等于/music/bands/the_beatles/ ,而HttpRequest.path_info為/minfo/music/bands/the_beatles/。 (5)、HttpRequest.method
字符串類(lèi)型,表示請(qǐng)求使用的HTTP方法。默認(rèn)為大寫(xiě)。 像這樣: if request.method == 'GET':
??? do_something()
elif request.method == 'POST':
??? do_something_else()1234 通過(guò)這個(gè)屬性來(lái)判斷請(qǐng)求的方法,然后根據(jù)請(qǐng)求的方法不同,在視圖中執(zhí)行不同的代碼。 (6)、HttpRequest.encoding
字符串類(lèi)型,表示提交的數(shù)據(jù)的編碼方式(如果為None 則表示使用DEFAULT_CHARSET設(shè)置)。 這個(gè)屬性是可寫(xiě)的,可以通過(guò)修改它來(lái)改變表單數(shù)據(jù)的編碼。任何隨后的屬性訪問(wèn)(例如GET或POST)將使用新的編碼方式。 (7)、HttpRequest.content_type
Django1.10中新增。表示從CONTENT_TYPE頭解析的請(qǐng)求的MIME類(lèi)型。 (8)、HttpRequest.content_params
Django 1.10中新增。包含在CONTENT_TYPE標(biāo)題中的鍵/值參數(shù)字典。 (9)、HttpRequest.GET
一個(gè)類(lèi)似于字典的對(duì)象,包含GET請(qǐng)求中的所有參數(shù)。 詳情參考QueryDict文檔。 (10)、HttpRequest.POST
一個(gè)包含所有POST請(qǐng)求的參數(shù),以及包含表單數(shù)據(jù)的字典。 詳情請(qǐng)參考QueryDict文檔。 如果需要訪問(wèn)請(qǐng)求中的原始或非表單數(shù)據(jù),可以使用HttpRequest.body屬性。 注意:請(qǐng)使用if request.method == “POST”來(lái)判斷一個(gè)請(qǐng)求是否POST類(lèi)型,而不要使用if request.POST。 POST中不包含上傳文件的數(shù)據(jù)。 (11)、HttpRequest.COOKIES
包含所有Cookie信息的字典。 鍵和值都為字符串。可以類(lèi)似字典類(lèi)型的方式,在cookie中讀寫(xiě)數(shù)據(jù),但是注意cookie是不安全的,因此,不要寫(xiě)敏感重要的信息。 (12)、HttpRequest.FILES
一個(gè)類(lèi)似于字典的對(duì)象,包含所有上傳的文件數(shù)據(jù)。 FILES中的每個(gè)鍵為<input type="file" name="" />中的name屬性值。 FILES中的每個(gè)值是一個(gè)UploadedFile。 要在Django中實(shí)現(xiàn)文件上傳,就要靠這個(gè)屬性! 如果請(qǐng)求方法是POST且請(qǐng)求的<form>中帶有enctype=”multipart/form-data”屬性,那么FILES將包含上傳的文件的數(shù)據(jù)。 否則,FILES將為一個(gè)空的類(lèi)似于字典的對(duì)象,屬于被忽略、無(wú)用的情形。 下面為使用模型處理上傳的文件的一個(gè)示例。 from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ModelFormWithFileField def upload_file(request):
??? if request.method == 'POST':
??????? form = ModelFormWithFileField(request.POST, request.FILES)
??????? if form.is_valid():
??????????? # 這么做就可以了,文件會(huì)被保存到Model中upload_to參數(shù)指定的位置
??????????? form.save()
??????????? return HttpResponseRedirect('/success/url/')
??? else:
??????? form = ModelFormWithFileField()
??? return render(request, 'upload.html', {'form': form})1234567891011121314 (13)、HttpRequest.META
包含所有HTTP頭部信息的字典。 可用的頭部信息取決于客戶端和服務(wù)器,下面是一些示例:
CONTENT_LENGTH —— 請(qǐng)求正文的長(zhǎng)度(以字符串計(jì))。
CONTENT_TYPE —— 請(qǐng)求正文的MIME類(lèi)型。
HTTP_ACCEPT —— 可接收的響應(yīng)Content-Type。
HTTP_ACCEPT_ENCODING —— 可接收的響應(yīng)編碼類(lèi)型。
HTTP_ACCEPT_LANGUAGE —— 可接收的響應(yīng)語(yǔ)言種類(lèi)。
HTTP_HOST —— 客服端發(fā)送的Host頭部。
HTTP_REFERER —— Referring頁(yè)面。
HTTP_USER_AGENT —— 客戶端的user-agent字符串。
QUERY_STRING —— 查詢字符串。
REMOTE_ADDR —— 客戶端的IP地址。想要獲取客戶端的ip信息,就在這里!
REMOTE_HOST —— 客戶端的主機(jī)名。
REMOTE_USER —— 服務(wù)器認(rèn)證后的用戶,如果可用。
REQUEST_METHOD —— 表示請(qǐng)求方法的字符串,例如”GET” 或”P(pán)OST”。
SERVER_NAME —— 服務(wù)器的主機(jī)名。
SERVER_PORT —— 服務(wù)器的端口(字符串)。
2)HttpRequest方法 (1)、HttpRequest.get_host()[source] 據(jù)HTTP_X_FORWARDED_HOST和HTTP_HOST頭部信息獲取請(qǐng)求的原始主機(jī)。 如果這兩個(gè)頭部沒(méi)有提供相應(yīng)的值,則使用SERVER_NAME和SERVER_PORT。 例如:”127.0.0.1:8000” 注:當(dāng)主機(jī)位于多個(gè)代理的后面,get_host()方法將會(huì)失敗。解決辦法之一是使用中間件重寫(xiě)代理的頭部 (2)、HttpRequest.get_port()[source]
使用META中HTTP_X_FORWARDED_PORT和SERVER_PORT的信息返回請(qǐng)求的始發(fā)端口。 (3)、HttpRequest.get_full_path()[source]
返回包含完整參數(shù)列表的path。例如:/music/bands/the_beatles/?print=true (4)、 HttpRequest.build_absolute_uri(location)[source] 返回location的絕對(duì)URI形式。 如果location沒(méi)有提供,則使用request.get_full_path()的值。 例如:”https://example.com/music/bands/the_beatles/?print=true” 注:不鼓勵(lì)在同一站點(diǎn)混合部署HTTP和HTTPS,如果需要將用戶重定向到HTTPS,最好使用Web服務(wù)器將所有HTTP流量重定向到HTTPS。 (5)、HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt=”, max_age=None)[source] 從已簽名的Cookie中獲取值,如果簽名不合法則返回django.core.signing.BadSignature。 可選參數(shù)salt用來(lái)為密碼加鹽,提高安全系數(shù)。 max_age參數(shù)用于檢查Cookie對(duì)應(yīng)的時(shí)間戳是否超時(shí)。 (6)、 HttpRequest.is_secure()[source]
如果使用的是Https,則返回True,表示連接是安全的。 (7)、HttpRequest.is_ajax()[source]
如果請(qǐng)求是通過(guò)XMLHttpRequest生成的,則返回True。 這個(gè)方法的作用就是判斷,當(dāng)前請(qǐng)求是否通過(guò)ajax機(jī)制發(fā)送過(guò)來(lái)的。 (8)、 HttpRequest.read(size=None)[source]
(9)、HttpRequest.readline()[source]
(10)、HttpRequest.readlines()[source]
(11)、 HttpRequest.xreadlines()[source]
(12)、 HttpRequest.iter()
上面的幾個(gè)方法都是從HttpRequest實(shí)例讀取文件數(shù)據(jù)的方法。 3)QueryDict對(duì)象 在應(yīng)用中我們主要操作的就是GET和POST屬性了。這里面包含了我們想要的數(shù)據(jù)。除了從QueryDict中獲取數(shù)據(jù),有時(shí)服務(wù)器還需要?jiǎng)?chuàng)建QueryDict對(duì)象發(fā)起向其他服務(wù)器的訪問(wèn)。 在HttpRequest對(duì)象中,GET和POST屬性都是一個(gè)django.http.QueryDict的實(shí)例。也就是說(shuō)你可以按本文下面提供的方法操作request.POST和request.GET。 3.1、QueryDict對(duì)象方法 QueryDict 實(shí)現(xiàn)了Python字典數(shù)據(jù)類(lèi)型的所有標(biāo)準(zhǔn)方法,因?yàn)樗亲值涞淖宇?lèi)。
不同之處在于下面: (1)、QueryDict.init(query_string=None, mutable=False, encoding=None)[source] QueryDict實(shí)例化方法。注意:QueryDict的鍵值是可以重復(fù)的! QueryDict('a=1&a=2&c=3')
返回:QueryDict: {'a': ['1', '2'], 'c': ['3']}>12 (2) 、classmethod QueryDict.fromkeys(iterable, value=”, mutable=False, encoding=None)[source] 循環(huán)將可迭代對(duì)象中的每個(gè)元素作為鍵值,并賦予同樣的值(來(lái)至value參數(shù))。 QueryDict.fromkeys(['a', 'a', 'b'], value='val')
返回:QueryDict: {'a': ['val', 'val'], 'b': ['val']}>12 (3)、 QueryDict.update(other_dict) 用新的QueryDict或字典更新當(dāng)前QueryDict。類(lèi)似dict.update(),但是追加內(nèi)容,而不是更新并替換它們 >>> q = QueryDict('a=1', mutable=True)
>>> q.update({'a': '2'})
>>> q.getlist('a')
['1', '2']
>>> q['a'] # returns the last
'2'123456 (4)、QueryDict.items() 類(lèi)似dict.items(),如果有重復(fù)項(xiàng)目,返回最近的一個(gè),而不是都返回: >>> q = QueryDict('a=1&a=2&a=3')
>>> q.items()
[('a', '3')]123 (5)、 QueryDict.values()
類(lèi)似dict.values(),但是只返回最近的值。 像這樣: >>> q = QueryDict('a=1&a=2&a=3')
>>> q.values()
['3']123 (6)、QueryDict.copy()[source]
使用copy.deepcopy()返回QueryDict對(duì)象的副本。 此副本是可變的! (7)、QueryDict.getlist(key, default=None)
返回鍵對(duì)應(yīng)的值列表。 如果該鍵不存在并且未提供默認(rèn)值,則返回一個(gè)空列表。 (8)、QueryDict.setlist(key, list_)[source]
為list_設(shè)置給定的鍵。 (9)、QueryDict.appendlist(key, item)[source]
將鍵追加到內(nèi)部與鍵相關(guān)聯(lián)的列表中。 (10)、QueryDict.setdefault(key, default=None)[source]
類(lèi)似dict.setdefault(),為某個(gè)鍵設(shè)置默認(rèn)值。 (11)、QueryDict.setlistdefault(key, default_list=None)[source]
類(lèi)似setdefault(),除了它需要的是一個(gè)值的列表而不是單個(gè)值。 (12)、QueryDict.lists()
類(lèi)似items(),只是它將其中的每個(gè)鍵的值作為列表放在一起。 像這樣: >>> q = QueryDict('a=1&a=2&a=3')
>>> q.lists()
[('a', ['1', '2', '3'])]123 (13)、QueryDict.pop(key)[source]
返回給定鍵的值的列表,并從QueryDict中移除該鍵。 如果鍵不存在,將引發(fā)KeyError。 像這樣: >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
>>> q.pop('a')
['1', '2', '3']123 (14)、QueryDict.popitem()[source]
刪除QueryDict任意一個(gè)鍵,并返回二值元組,包含鍵和鍵的所有值的列表。在一個(gè)空的字典上調(diào)用時(shí)將引發(fā)KeyError。 像這樣: >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])123 (15)、QueryDict.dict()
將QueryDict轉(zhuǎn)換為Python的字典數(shù)據(jù)類(lèi)型,并返回該字典。 如果出現(xiàn)重復(fù)的鍵,則將所有的值打包成一個(gè)列表,最為新字典中鍵的值。 >>> q = QueryDict('a=1&a=3&a=5')
>>> q.dict()
{'a': '5'}123 (16)、QueryDict.urlencode(safe=None)[source]
已url的編碼格式返回?cái)?shù)據(jù)字符串。 像這樣: >>> q = QueryDict('a=2&b=3&b=5')
>>> q.urlencode()
'a=2&b=3&b=5'123 使用safe參數(shù)傳遞不需要編碼的字符。 像這樣: >>> q = QueryDict(mutable=True)
>>> q['next'] = '/a&b/'
>>> q.urlencode(safe='/')
'next=/a%26b/'
HttpResponse.content
響應(yīng)的內(nèi)容。bytes類(lèi)型。
HttpResponse.charset
編碼的字符集。 如果沒(méi)指定,將會(huì)從content_type中解析出來(lái)。
HttpResponse.status_code
響應(yīng)的狀態(tài)碼,比如200。
HttpResponse.reason_phrase
響應(yīng)的HTTP原因短語(yǔ)。 使用標(biāo)準(zhǔn)原因短語(yǔ)。
除非明確設(shè)置,否則reason_phrase由status_code的值決定。
HttpResponse.streaming
這個(gè)屬性的值總是False。由于這個(gè)屬性的存在,使得中間件能夠區(qū)別對(duì)待流式響應(yīng)和常規(guī)響應(yīng)。
HttpResponse.closed
如果響應(yīng)已關(guān)閉,那么這個(gè)屬性的值為T(mén)rue。
1)HttpResponse.init(content=”, content_type=None, status=200, reason=None, charset=None)[source]
響應(yīng)的實(shí)例化方法。使用content參數(shù)和content-type實(shí)例化一個(gè)HttpResponse對(duì)象。 content應(yīng)該是一個(gè)迭代器或者字符串。如果是迭代器,這個(gè)迭代期返回的應(yīng)是一串字符串,并且這些字符串連接起來(lái)形成response的內(nèi)容。 如果不是迭代器或者字符串,那么在其被接收的時(shí)候?qū)⑥D(zhuǎn)換成字符串。 content_type是可選地,用于填充HTTP的Content-Type頭部。如果未指定,默認(rèn)情況下由DEFAULT_CONTENT_TYPE和DEFAULT_CHARSET設(shè)置組成:text/html; charset=utf-8。 status是響應(yīng)的狀態(tài)碼。reason是HTTP響應(yīng)短語(yǔ)。charset是編碼方式。 2) HttpResponse.has_header(header)
檢查頭部中是否有給定的名稱(不區(qū)分大小寫(xiě)),返回True或 False。 3)HttpResponse.setdefault(header, value)
設(shè)置一個(gè)頭部,除非該頭部已經(jīng)設(shè)置過(guò)了。 4)HttpResponse.set_cookie(key, value=”, max_age=None, expires=None, path=’/’, domain=None, secure=None, httponly=False)
設(shè)置一個(gè)Cookie。 參數(shù)與Python標(biāo)準(zhǔn)庫(kù)中的Morsel.Cookie對(duì)象相同。 max_age: 生存周期,以秒為單位。 expires:到期時(shí)間。 domain: 用于設(shè)置跨域的Cookie。例如domain=”.lawrence.com”將設(shè)置一個(gè)www.lawrence.com、blogs.lawrence.com和calendars.lawrence.com都可讀的Cookie。 否則,Cookie將只能被設(shè)置它的域讀取。 如果你想阻止客服端的JavaScript訪問(wèn)Cookie,可以設(shè)置httponly=True。 5) HttpResponse.set_signed_cookie(key, value, salt=”, max_age=None, expires=None, path=’/’, domain=None, secure=None, httponly=True)
與set_cookie()類(lèi)似,但是在設(shè)置之前將對(duì)cookie進(jìn)行加密簽名。通常與HttpRequest.get_signed_cookie()一起使用。 6) HttpResponse.delete_cookie(key, path=’/’, domain=None)
刪除Cookie中指定的key。 由于Cookie的工作方式,path和domain應(yīng)該與set_cookie()中使用的值相同,否則Cookie不會(huì)刪掉。 7) HttpResponse.write(content)[source]
將HttpResponse實(shí)例看作類(lèi)似文件的對(duì)象,往里面添加內(nèi)容。 8) HttpResponse.flush()
清空HttpResponse實(shí)例的內(nèi)容。 9) HttpResponse.tell()[source]
將HttpResponse實(shí)例看作類(lèi)似文件的對(duì)象,移動(dòng)位置指針。 10) HttpResponse.getvalue()[source]
返回HttpResponse.content的值。 此方法將HttpResponse實(shí)例看作是一個(gè)類(lèi)似流的對(duì)象。 11) HttpResponse.readable()
Django1.10中的新功能,值始終為False。 12) HttpResponse.seekable()
Django1.10中的新功能,值始終為False。 13) HttpResponse.writable()[source]
Django1.10中的新功能,值始終為T(mén)rue。 14) HttpResponse.writelines(lines)[source]
將一個(gè)包含行的列表寫(xiě)入響應(yīng)對(duì)象中。 不添加分行符。
??? ...
??? return HttpResponse("接收數(shù)據(jù)成功")?? # 直接返回響應(yīng)字符串123 當(dāng)我們想以字符串的形式返回我們從數(shù)據(jù)查詢到的數(shù)據(jù)集或數(shù)據(jù)對(duì)象時(shí),可以使用序列化功能。 from django.core import serializers jsonstr1 = serializers.serialize("json", dataset1)?? # 將dataset轉(zhuǎn)化為json字符串
return HttpResponse(jsonstr1 )1234 我們也可以直接返回html源代碼的字符串形式,這樣前端瀏覽器就會(huì)自動(dòng)渲染成頁(yè)面 html = "<html><body>It is now %s.</body></html>" % datetime.datetime.now()
return HttpResponse(html)12
from .models import User,Diary
from django.forms.models import model_to_dict # 返回字典
def finduser(request):
??? userid = request.POST.get("userid", None)? # 讀取數(shù)據(jù)
??? users = User.objects.filter(id=userid)? # 獲取一個(gè)用戶,返回QuerySet
??? user = users[0]? # 獲取第一個(gè)user對(duì)象
??? user_dict1 = model_to_dict(user)? # 將對(duì)象轉(zhuǎn)化為字典
??? return JsonResponse(user_dict1)? # 返回前端字典1234567891011
response = FileResponse(open('myfile.png', 'rb'))12
<html lang="en">
<head>
??? <meta charset="UTF-8">
??? <title>用戶登錄</title>
</head>
<body>
??? <form action="/app1/insert/" method="post">
??????? <input type="text" name="username"/>
??????? <input type="password" name="password"/>
??????? <input type="submit" value="提交">
??? </form>
</body>
</html>1234567891011121314 有了html文件,我們?cè)趘iews.py文件內(nèi)新建一個(gè)insertuser視圖函數(shù),返回這個(gè)模板頁(yè)面。 from django.shortcuts import render_to_response,redirect
from .models import User,Diary
import time
def insertuser(request):
??? return render_to_response('insert.html')? # 返回文件響應(yīng)1234567
? 其實(shí),python只是加載html文件,讀取內(nèi)容后,將內(nèi)容返回給前臺(tái)。所以是不是html格式并不重要。我們完全可以使用txt格式存儲(chǔ)。在views.py文件的函數(shù)中加載txt文件。
上面的模板文件只是靜態(tài)的html文件。在views視圖函數(shù)中是不能動(dòng)態(tài)修改的。如果我們想根據(jù)數(shù)據(jù)庫(kù)查詢結(jié)果動(dòng)態(tài)的修改模板頁(yè)面,形成新的頁(yè)面再返回給前端怎么辦? 我們把views中的函數(shù)用于邏輯處理,把處理結(jié)果交給html模板對(duì)象,來(lái)渲染成最終形成的html頁(yè)面。這個(gè)過(guò)程我們稱為渲染視圖。 我們?cè)趖emplates文件夾新建另一個(gè)html文件為showuser.html。內(nèi)容如下 <!DOCTYPE html>
<html lang="en">
<head>
??? <meta charset="UTF-8">
??? <title>Title</title>
</head>
<body>
??? <h1>信息展示</h1>
??? <table>
??? <tr>
??????? <th>用戶名</th>
??????? <th>密碼</th>
??? </tr>
??? {% for line in people_list %}
??? <tr>
??????? <td>{{line.username}}</td>
??????? <td>{{line.password}}</td>
??? </tr>
??? {% endfor %}
??? </table>
</body>
</html>12345678910111213141516171819202122 我們可以看到在html文件的代碼中包含了部分python代碼。至于則個(gè)動(dòng)態(tài)模板的書(shū)寫(xiě)規(guī)則以及如果使用view視圖函數(shù)傳遞的數(shù)據(jù)的, 我們?cè)诹硪黄恼聇emplates模板中再詳解。 不過(guò)這里我們需要知道在views視圖函數(shù)中如何向模板傳遞數(shù)據(jù)。 我們?cè)趘iews.py中實(shí)現(xiàn)findalluser函數(shù),代碼如下: from django.shortcuts import render_to_response
from .models import User,Diary # findalluser將數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù)讀出并展示出來(lái)。
def findalluser(request):
??? allpeople = User.objects.all()? # 查詢所有用戶
??? dict={
??????? 'people_list':allpeople
??? }
??? return render_to_response("showuser.html",dict)? # 返回文件響應(yīng),第二個(gè)參數(shù)必須為字典12345678910 視圖函數(shù)將數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù)讀出并結(jié)合html文件渲染出最后的響應(yīng)html源代碼。這和jsp中的原理相同,python先將html文件的內(nèi)容全部加載到內(nèi)存中, 再根據(jù)python的語(yǔ)法和傳來(lái)的數(shù)據(jù)庫(kù)數(shù)據(jù)生成html文件中python代碼部分產(chǎn)生的文本,再將最終生成的html源代碼返回到前端。 注意:在向模板傳遞參數(shù)時(shí)必須以字典的形式傳遞。
? 渲染的模板視圖生成的是html頁(yè)面,只能在瀏覽器中打開(kāi)。移動(dòng)互聯(lián)網(wǎng)下的移動(dòng)設(shè)備端是無(wú)法處理的。所以傳輸字典對(duì)象的形式更為流行。
request:視圖函數(shù)處理的當(dāng)前請(qǐng)求,封裝了請(qǐng)求頭的所有數(shù)據(jù),其實(shí)就是視圖參數(shù)request。
template_name:要使用的模板的完整名稱或者模板名稱的列表。如果是一個(gè)列表,將使用其中能夠查找到的第一個(gè)模板。
可選參數(shù):
context:添加到模板上下文的一個(gè)數(shù)據(jù)字典。默認(rèn)是一個(gè)空字典。可以將認(rèn)可需要提供給模板的數(shù)據(jù)以字典的格式添加進(jìn)去。這里有個(gè)小技巧,使用Python內(nèi)置的locals()方法,可以方便的將函數(shù)作用于內(nèi)的所有變量一次性添加。
content_type:用于生成的文檔的MIME類(lèi)型。 默認(rèn)為DEFAULT_CONTENT_TYPE設(shè)置的值。
status:響應(yīng)的狀態(tài)代碼。 默認(rèn)為200。
using:用于加載模板使用的模板引擎的NAME。
使用render可以同時(shí)處理請(qǐng)求對(duì)象request、html模板、數(shù)據(jù)庫(kù)數(shù)據(jù)。在Django中可以調(diào)用render函數(shù),也可以在模板對(duì)象上調(diào)用render函數(shù)。 1、調(diào)用全局render函數(shù)。看如下代碼: from django.shortcuts import render
from .models import User,Diary # findalluser將數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù)讀出并展示出來(lái)。
def findalluser(request):
??? allpeople = User.objects.all()? # 查詢所有用戶
??? dict={
??????? 'people_list':allpeople
??? }
??? return render(request,'showuser.html',dict)12345678910 render()函數(shù)的第一個(gè)位置參數(shù)是請(qǐng)求對(duì)象(就是view函數(shù)的第一個(gè)參數(shù)),第二個(gè)位置參數(shù)是模板。還可以有一個(gè)可選的第三參數(shù),一個(gè)字典,包含需要傳遞給模板的數(shù)據(jù)。最后render函數(shù)返回一個(gè)經(jīng)過(guò)字典數(shù)據(jù)渲染過(guò)的模板封裝而成的HttpResponse對(duì)象。 2、在template模板對(duì)象上調(diào)用render函數(shù)。如下示例 from django.shortcuts import render,HttpResponse def findalluser(request):
??? allpeople = models.User.objects.all()? # 查詢所有用戶
??? dict={
??????? 'people_list':allpeople
??? }
??? template = loader.get_template('showuser.html')? # 加載模板對(duì)象
??? return HttpResponse(template.render(dict1, request))? # 渲染視圖
一、HttpRequest捕獲請(qǐng)求
捕獲請(qǐng)求——HttpRequest對(duì)象1、屬性
HttpRequest.scheme? #一個(gè)字符串,表示請(qǐng)求的方案(通常是http或者h(yuǎn)ttps)HttpRequest.body??? #一個(gè)字節(jié)字符串,表示原始HTTP請(qǐng)求的正文
HttpRequest.path??? #一個(gè)字符串,表示請(qǐng)求的頁(yè)面的完整路徑,不包含域名
HttpRequest.methed?? #一個(gè)字符串,表示請(qǐng)求使用的HTTP方法,必須使用大寫(xiě)
HttpRequest.GET????? #一個(gè)類(lèi)似于字典的對(duì)象,包含HTTP GET的所有參數(shù)
HttpRequest.POST???? #一個(gè)包含所有給定的HTTP POST參數(shù)的類(lèi)字典對(duì)象,提供了包含表單數(shù)據(jù)的請(qǐng)求
HttpRequest.COOKIES??? #一個(gè)標(biāo)準(zhǔn)的python字典,包含所有cookie,鍵和值都為字符串
HttpRequest.FILES???? #一個(gè)類(lèi)似于字典的對(duì)象,包含所有的上傳文件
HttpRequest.META????? #一個(gè)標(biāo)準(zhǔn)的python字典,包含所有的HTTP頭部123456789
2、方法
HttpRequest.get_host()#返回請(qǐng)求的原始主機(jī)HttpRequest.get_full_path()#返回path,如果可以將加上查詢字符串
HttpRequest.read(size=None)
HttpRequest.readline()
HttpRequest.readlines()
HttpRequest.xreadlines()
HttpRequest.__iter__()
#這幾個(gè)方法實(shí)現(xiàn)類(lèi)文件的接口用于讀取HttpRequest.示例。這使得可以用流的方式讀#取進(jìn)來(lái)的請(qǐng)求,一個(gè)常見(jiàn)的用例是使用迭代解析器處理大型XML有效載荷, 而不是內(nèi)存#中構(gòu)造一個(gè)完整的XML樹(shù)。
3、詳解
每當(dāng)一個(gè)用戶請(qǐng)求發(fā)送過(guò)來(lái),Django將HTTP數(shù)據(jù)包中的相關(guān)內(nèi)容,打包成為一個(gè)HttpRequest對(duì)象,并傳遞給每個(gè)視圖函數(shù)作為第一位置參數(shù), 也就是request,供我們調(diào)用,這一過(guò)程是系統(tǒng)自動(dòng)完成的。 例如:前臺(tái)請(qǐng)求數(shù)據(jù)包含username和password兩個(gè)字段。例如網(wǎng)址http://127.0.0.1/xxxx/xxx?username=luanpeng&password=123其中的xxx為網(wǎng)址映射,在urlsl路由映射部分再做詳解。 # 接收請(qǐng)求數(shù)據(jù)返回字符串響應(yīng)
def index(request):
??? if request.method == "POST":
??????? username = request.POST.get("username", None)?? # 讀取post數(shù)據(jù),None為默認(rèn)值
??????? password = request.POST.get("password", None)?? # 讀取post數(shù)據(jù),None為默認(rèn)值
??? if request.method == "GET":
??????? username = request.GET.get("username", None)?? # 讀取get數(shù)據(jù)
??????? password = request.GET.get("password", None)? # 讀取get數(shù)據(jù)
??? ...123456789 在獲取數(shù)據(jù)時(shí),通常會(huì)提供一個(gè)默認(rèn)值,防止請(qǐng)求數(shù)據(jù)中沒(méi)有目標(biāo)屬性時(shí)觸發(fā)KeyError異常。 不僅如此,HttpRequest對(duì)象中包含了非常多的重要的信息和數(shù)據(jù),應(yīng)該熟練掌握它。 1)HttpRequest屬性 (1)、 HttpRequest.scheme
字符串類(lèi)型,表示請(qǐng)求的協(xié)議種類(lèi),’http’或’https’。 (2)、 HttpRequest.body
bytes類(lèi)型,表示原始HTTP請(qǐng)求的正文。它對(duì)于處理非HTML形式的數(shù)據(jù)非常有用:二進(jìn)制圖像、XML等。如果要處理常規(guī)的表單數(shù)據(jù),應(yīng)該使用HttpRequest.POST。還可以使用類(lèi)似讀寫(xiě)文件的方式從HttpRequest中讀取數(shù)據(jù),參見(jiàn)HttpRequest.read()。 (3)、 HttpRequest.path
字符串類(lèi)型,表示當(dāng)前請(qǐng)求頁(yè)面的完整路徑,但是不包括協(xié)議名和域名。例如:”/music/bands/the_beatles/”。這個(gè)屬性,常被用于我們進(jìn)行某項(xiàng)操作時(shí),如果不通過(guò),返回用戶先前瀏覽的頁(yè)面。非常有用! (4)、 HttpRequest.path_info
在某些Web服務(wù)器配置下,主機(jī)名后的URL部分被分成腳本前綴部分和路徑信息部分。path_info 屬性將始終包含路徑信息部分,不論使用的Web服務(wù)器是什么。使用它代替path可以讓代碼在測(cè)試和開(kāi)發(fā)環(huán)境中更容易地切換。
例如,如果應(yīng)用的WSGIScriptAlias設(shè)置為/minfo,那么HttpRequest.path等于/music/bands/the_beatles/ ,而HttpRequest.path_info為/minfo/music/bands/the_beatles/。 (5)、HttpRequest.method
字符串類(lèi)型,表示請(qǐng)求使用的HTTP方法。默認(rèn)為大寫(xiě)。 像這樣: if request.method == 'GET':
??? do_something()
elif request.method == 'POST':
??? do_something_else()1234 通過(guò)這個(gè)屬性來(lái)判斷請(qǐng)求的方法,然后根據(jù)請(qǐng)求的方法不同,在視圖中執(zhí)行不同的代碼。 (6)、HttpRequest.encoding
字符串類(lèi)型,表示提交的數(shù)據(jù)的編碼方式(如果為None 則表示使用DEFAULT_CHARSET設(shè)置)。 這個(gè)屬性是可寫(xiě)的,可以通過(guò)修改它來(lái)改變表單數(shù)據(jù)的編碼。任何隨后的屬性訪問(wèn)(例如GET或POST)將使用新的編碼方式。 (7)、HttpRequest.content_type
Django1.10中新增。表示從CONTENT_TYPE頭解析的請(qǐng)求的MIME類(lèi)型。 (8)、HttpRequest.content_params
Django 1.10中新增。包含在CONTENT_TYPE標(biāo)題中的鍵/值參數(shù)字典。 (9)、HttpRequest.GET
一個(gè)類(lèi)似于字典的對(duì)象,包含GET請(qǐng)求中的所有參數(shù)。 詳情參考QueryDict文檔。 (10)、HttpRequest.POST
一個(gè)包含所有POST請(qǐng)求的參數(shù),以及包含表單數(shù)據(jù)的字典。 詳情請(qǐng)參考QueryDict文檔。 如果需要訪問(wèn)請(qǐng)求中的原始或非表單數(shù)據(jù),可以使用HttpRequest.body屬性。 注意:請(qǐng)使用if request.method == “POST”來(lái)判斷一個(gè)請(qǐng)求是否POST類(lèi)型,而不要使用if request.POST。 POST中不包含上傳文件的數(shù)據(jù)。 (11)、HttpRequest.COOKIES
包含所有Cookie信息的字典。 鍵和值都為字符串。可以類(lèi)似字典類(lèi)型的方式,在cookie中讀寫(xiě)數(shù)據(jù),但是注意cookie是不安全的,因此,不要寫(xiě)敏感重要的信息。 (12)、HttpRequest.FILES
一個(gè)類(lèi)似于字典的對(duì)象,包含所有上傳的文件數(shù)據(jù)。 FILES中的每個(gè)鍵為<input type="file" name="" />中的name屬性值。 FILES中的每個(gè)值是一個(gè)UploadedFile。 要在Django中實(shí)現(xiàn)文件上傳,就要靠這個(gè)屬性! 如果請(qǐng)求方法是POST且請(qǐng)求的<form>中帶有enctype=”multipart/form-data”屬性,那么FILES將包含上傳的文件的數(shù)據(jù)。 否則,FILES將為一個(gè)空的類(lèi)似于字典的對(duì)象,屬于被忽略、無(wú)用的情形。 下面為使用模型處理上傳的文件的一個(gè)示例。 from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ModelFormWithFileField def upload_file(request):
??? if request.method == 'POST':
??????? form = ModelFormWithFileField(request.POST, request.FILES)
??????? if form.is_valid():
??????????? # 這么做就可以了,文件會(huì)被保存到Model中upload_to參數(shù)指定的位置
??????????? form.save()
??????????? return HttpResponseRedirect('/success/url/')
??? else:
??????? form = ModelFormWithFileField()
??? return render(request, 'upload.html', {'form': form})1234567891011121314 (13)、HttpRequest.META
包含所有HTTP頭部信息的字典。 可用的頭部信息取決于客戶端和服務(wù)器,下面是一些示例:
CONTENT_LENGTH —— 請(qǐng)求正文的長(zhǎng)度(以字符串計(jì))。
CONTENT_TYPE —— 請(qǐng)求正文的MIME類(lèi)型。
HTTP_ACCEPT —— 可接收的響應(yīng)Content-Type。
HTTP_ACCEPT_ENCODING —— 可接收的響應(yīng)編碼類(lèi)型。
HTTP_ACCEPT_LANGUAGE —— 可接收的響應(yīng)語(yǔ)言種類(lèi)。
HTTP_HOST —— 客服端發(fā)送的Host頭部。
HTTP_REFERER —— Referring頁(yè)面。
HTTP_USER_AGENT —— 客戶端的user-agent字符串。
QUERY_STRING —— 查詢字符串。
REMOTE_ADDR —— 客戶端的IP地址。想要獲取客戶端的ip信息,就在這里!
REMOTE_HOST —— 客戶端的主機(jī)名。
REMOTE_USER —— 服務(wù)器認(rèn)證后的用戶,如果可用。
REQUEST_METHOD —— 表示請(qǐng)求方法的字符串,例如”GET” 或”P(pán)OST”。
SERVER_NAME —— 服務(wù)器的主機(jī)名。
SERVER_PORT —— 服務(wù)器的端口(字符串)。
2)HttpRequest方法 (1)、HttpRequest.get_host()[source] 據(jù)HTTP_X_FORWARDED_HOST和HTTP_HOST頭部信息獲取請(qǐng)求的原始主機(jī)。 如果這兩個(gè)頭部沒(méi)有提供相應(yīng)的值,則使用SERVER_NAME和SERVER_PORT。 例如:”127.0.0.1:8000” 注:當(dāng)主機(jī)位于多個(gè)代理的后面,get_host()方法將會(huì)失敗。解決辦法之一是使用中間件重寫(xiě)代理的頭部 (2)、HttpRequest.get_port()[source]
使用META中HTTP_X_FORWARDED_PORT和SERVER_PORT的信息返回請(qǐng)求的始發(fā)端口。 (3)、HttpRequest.get_full_path()[source]
返回包含完整參數(shù)列表的path。例如:/music/bands/the_beatles/?print=true (4)、 HttpRequest.build_absolute_uri(location)[source] 返回location的絕對(duì)URI形式。 如果location沒(méi)有提供,則使用request.get_full_path()的值。 例如:”https://example.com/music/bands/the_beatles/?print=true” 注:不鼓勵(lì)在同一站點(diǎn)混合部署HTTP和HTTPS,如果需要將用戶重定向到HTTPS,最好使用Web服務(wù)器將所有HTTP流量重定向到HTTPS。 (5)、HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt=”, max_age=None)[source] 從已簽名的Cookie中獲取值,如果簽名不合法則返回django.core.signing.BadSignature。 可選參數(shù)salt用來(lái)為密碼加鹽,提高安全系數(shù)。 max_age參數(shù)用于檢查Cookie對(duì)應(yīng)的時(shí)間戳是否超時(shí)。 (6)、 HttpRequest.is_secure()[source]
如果使用的是Https,則返回True,表示連接是安全的。 (7)、HttpRequest.is_ajax()[source]
如果請(qǐng)求是通過(guò)XMLHttpRequest生成的,則返回True。 這個(gè)方法的作用就是判斷,當(dāng)前請(qǐng)求是否通過(guò)ajax機(jī)制發(fā)送過(guò)來(lái)的。 (8)、 HttpRequest.read(size=None)[source]
(9)、HttpRequest.readline()[source]
(10)、HttpRequest.readlines()[source]
(11)、 HttpRequest.xreadlines()[source]
(12)、 HttpRequest.iter()
上面的幾個(gè)方法都是從HttpRequest實(shí)例讀取文件數(shù)據(jù)的方法。 3)QueryDict對(duì)象 在應(yīng)用中我們主要操作的就是GET和POST屬性了。這里面包含了我們想要的數(shù)據(jù)。除了從QueryDict中獲取數(shù)據(jù),有時(shí)服務(wù)器還需要?jiǎng)?chuàng)建QueryDict對(duì)象發(fā)起向其他服務(wù)器的訪問(wèn)。 在HttpRequest對(duì)象中,GET和POST屬性都是一個(gè)django.http.QueryDict的實(shí)例。也就是說(shuō)你可以按本文下面提供的方法操作request.POST和request.GET。 3.1、QueryDict對(duì)象方法 QueryDict 實(shí)現(xiàn)了Python字典數(shù)據(jù)類(lèi)型的所有標(biāo)準(zhǔn)方法,因?yàn)樗亲值涞淖宇?lèi)。
不同之處在于下面: (1)、QueryDict.init(query_string=None, mutable=False, encoding=None)[source] QueryDict實(shí)例化方法。注意:QueryDict的鍵值是可以重復(fù)的! QueryDict('a=1&a=2&c=3')
返回:QueryDict: {'a': ['1', '2'], 'c': ['3']}>12 (2) 、classmethod QueryDict.fromkeys(iterable, value=”, mutable=False, encoding=None)[source] 循環(huán)將可迭代對(duì)象中的每個(gè)元素作為鍵值,并賦予同樣的值(來(lái)至value參數(shù))。 QueryDict.fromkeys(['a', 'a', 'b'], value='val')
返回:QueryDict: {'a': ['val', 'val'], 'b': ['val']}>12 (3)、 QueryDict.update(other_dict) 用新的QueryDict或字典更新當(dāng)前QueryDict。類(lèi)似dict.update(),但是追加內(nèi)容,而不是更新并替換它們 >>> q = QueryDict('a=1', mutable=True)
>>> q.update({'a': '2'})
>>> q.getlist('a')
['1', '2']
>>> q['a'] # returns the last
'2'123456 (4)、QueryDict.items() 類(lèi)似dict.items(),如果有重復(fù)項(xiàng)目,返回最近的一個(gè),而不是都返回: >>> q = QueryDict('a=1&a=2&a=3')
>>> q.items()
[('a', '3')]123 (5)、 QueryDict.values()
類(lèi)似dict.values(),但是只返回最近的值。 像這樣: >>> q = QueryDict('a=1&a=2&a=3')
>>> q.values()
['3']123 (6)、QueryDict.copy()[source]
使用copy.deepcopy()返回QueryDict對(duì)象的副本。 此副本是可變的! (7)、QueryDict.getlist(key, default=None)
返回鍵對(duì)應(yīng)的值列表。 如果該鍵不存在并且未提供默認(rèn)值,則返回一個(gè)空列表。 (8)、QueryDict.setlist(key, list_)[source]
為list_設(shè)置給定的鍵。 (9)、QueryDict.appendlist(key, item)[source]
將鍵追加到內(nèi)部與鍵相關(guān)聯(lián)的列表中。 (10)、QueryDict.setdefault(key, default=None)[source]
類(lèi)似dict.setdefault(),為某個(gè)鍵設(shè)置默認(rèn)值。 (11)、QueryDict.setlistdefault(key, default_list=None)[source]
類(lèi)似setdefault(),除了它需要的是一個(gè)值的列表而不是單個(gè)值。 (12)、QueryDict.lists()
類(lèi)似items(),只是它將其中的每個(gè)鍵的值作為列表放在一起。 像這樣: >>> q = QueryDict('a=1&a=2&a=3')
>>> q.lists()
[('a', ['1', '2', '3'])]123 (13)、QueryDict.pop(key)[source]
返回給定鍵的值的列表,并從QueryDict中移除該鍵。 如果鍵不存在,將引發(fā)KeyError。 像這樣: >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
>>> q.pop('a')
['1', '2', '3']123 (14)、QueryDict.popitem()[source]
刪除QueryDict任意一個(gè)鍵,并返回二值元組,包含鍵和鍵的所有值的列表。在一個(gè)空的字典上調(diào)用時(shí)將引發(fā)KeyError。 像這樣: >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])123 (15)、QueryDict.dict()
將QueryDict轉(zhuǎn)換為Python的字典數(shù)據(jù)類(lèi)型,并返回該字典。 如果出現(xiàn)重復(fù)的鍵,則將所有的值打包成一個(gè)列表,最為新字典中鍵的值。 >>> q = QueryDict('a=1&a=3&a=5')
>>> q.dict()
{'a': '5'}123 (16)、QueryDict.urlencode(safe=None)[source]
已url的編碼格式返回?cái)?shù)據(jù)字符串。 像這樣: >>> q = QueryDict('a=2&b=3&b=5')
>>> q.urlencode()
'a=2&b=3&b=5'123 使用safe參數(shù)傳遞不需要編碼的字符。 像這樣: >>> q = QueryDict(mutable=True)
>>> q['next'] = '/a&b/'
>>> q.urlencode(safe='/')
'next=/a%26b/'
二、HttpResponseWeb響應(yīng)
Web響應(yīng)——HttpResponse
它是作用是內(nèi)部傳入一個(gè)字符串參數(shù),然后發(fā)給瀏覽器。 例如: def index(request): # 業(yè)務(wù)邏輯代碼 return HttpResponse("OK") view視圖函數(shù)返回給前端的是HttpResponse對(duì)象,HttpResponse類(lèi)定義在django.http模塊中。 HttpRequest對(duì)象由Django自動(dòng)創(chuàng)建,而HttpResponse對(duì)象則由程序員手動(dòng)創(chuàng)建. 我們編寫(xiě)的每個(gè)視圖都要實(shí)例化、填充和返回一個(gè)HttpResponse對(duì)象。也就是函數(shù)的return值。數(shù)據(jù)表現(xiàn)有多種形式,可以是字符串、對(duì)象、網(wǎng)頁(yè)。 HttpResponse屬性HttpResponse.content
響應(yīng)的內(nèi)容。bytes類(lèi)型。
HttpResponse.charset
編碼的字符集。 如果沒(méi)指定,將會(huì)從content_type中解析出來(lái)。
HttpResponse.status_code
響應(yīng)的狀態(tài)碼,比如200。
HttpResponse.reason_phrase
響應(yīng)的HTTP原因短語(yǔ)。 使用標(biāo)準(zhǔn)原因短語(yǔ)。
除非明確設(shè)置,否則reason_phrase由status_code的值決定。
HttpResponse.streaming
這個(gè)屬性的值總是False。由于這個(gè)屬性的存在,使得中間件能夠區(qū)別對(duì)待流式響應(yīng)和常規(guī)響應(yīng)。
HttpResponse.closed
如果響應(yīng)已關(guān)閉,那么這個(gè)屬性的值為T(mén)rue。
1、HttpResponse方法
1)HttpResponse.init(content=”, content_type=None, status=200, reason=None, charset=None)[source] 響應(yīng)的實(shí)例化方法。使用content參數(shù)和content-type實(shí)例化一個(gè)HttpResponse對(duì)象。 content應(yīng)該是一個(gè)迭代器或者字符串。如果是迭代器,這個(gè)迭代期返回的應(yīng)是一串字符串,并且這些字符串連接起來(lái)形成response的內(nèi)容。 如果不是迭代器或者字符串,那么在其被接收的時(shí)候?qū)⑥D(zhuǎn)換成字符串。 content_type是可選地,用于填充HTTP的Content-Type頭部。如果未指定,默認(rèn)情況下由DEFAULT_CONTENT_TYPE和DEFAULT_CHARSET設(shè)置組成:text/html; charset=utf-8。 status是響應(yīng)的狀態(tài)碼。reason是HTTP響應(yīng)短語(yǔ)。charset是編碼方式。 2) HttpResponse.has_header(header)
檢查頭部中是否有給定的名稱(不區(qū)分大小寫(xiě)),返回True或 False。 3)HttpResponse.setdefault(header, value)
設(shè)置一個(gè)頭部,除非該頭部已經(jīng)設(shè)置過(guò)了。 4)HttpResponse.set_cookie(key, value=”, max_age=None, expires=None, path=’/’, domain=None, secure=None, httponly=False)
設(shè)置一個(gè)Cookie。 參數(shù)與Python標(biāo)準(zhǔn)庫(kù)中的Morsel.Cookie對(duì)象相同。 max_age: 生存周期,以秒為單位。 expires:到期時(shí)間。 domain: 用于設(shè)置跨域的Cookie。例如domain=”.lawrence.com”將設(shè)置一個(gè)www.lawrence.com、blogs.lawrence.com和calendars.lawrence.com都可讀的Cookie。 否則,Cookie將只能被設(shè)置它的域讀取。 如果你想阻止客服端的JavaScript訪問(wèn)Cookie,可以設(shè)置httponly=True。 5) HttpResponse.set_signed_cookie(key, value, salt=”, max_age=None, expires=None, path=’/’, domain=None, secure=None, httponly=True)
與set_cookie()類(lèi)似,但是在設(shè)置之前將對(duì)cookie進(jìn)行加密簽名。通常與HttpRequest.get_signed_cookie()一起使用。 6) HttpResponse.delete_cookie(key, path=’/’, domain=None)
刪除Cookie中指定的key。 由于Cookie的工作方式,path和domain應(yīng)該與set_cookie()中使用的值相同,否則Cookie不會(huì)刪掉。 7) HttpResponse.write(content)[source]
將HttpResponse實(shí)例看作類(lèi)似文件的對(duì)象,往里面添加內(nèi)容。 8) HttpResponse.flush()
清空HttpResponse實(shí)例的內(nèi)容。 9) HttpResponse.tell()[source]
將HttpResponse實(shí)例看作類(lèi)似文件的對(duì)象,移動(dòng)位置指針。 10) HttpResponse.getvalue()[source]
返回HttpResponse.content的值。 此方法將HttpResponse實(shí)例看作是一個(gè)類(lèi)似流的對(duì)象。 11) HttpResponse.readable()
Django1.10中的新功能,值始終為False。 12) HttpResponse.seekable()
Django1.10中的新功能,值始終為False。 13) HttpResponse.writable()[source]
Django1.10中的新功能,值始終為T(mén)rue。 14) HttpResponse.writelines(lines)[source]
將一個(gè)包含行的列表寫(xiě)入響應(yīng)對(duì)象中。 不添加分行符。
2.1 返回前臺(tái)字符串
Django使用HttpResponse基類(lèi)返回前端字符串。簡(jiǎn)單的返回如下 def test(request):??? ...
??? return HttpResponse("接收數(shù)據(jù)成功")?? # 直接返回響應(yīng)字符串123 當(dāng)我們想以字符串的形式返回我們從數(shù)據(jù)查詢到的數(shù)據(jù)集或數(shù)據(jù)對(duì)象時(shí),可以使用序列化功能。 from django.core import serializers jsonstr1 = serializers.serialize("json", dataset1)?? # 將dataset轉(zhuǎn)化為json字符串
return HttpResponse(jsonstr1 )1234 我們也可以直接返回html源代碼的字符串形式,這樣前端瀏覽器就會(huì)自動(dòng)渲染成頁(yè)面 html = "<html><body>It is now %s.</body></html>" % datetime.datetime.now()
return HttpResponse(html)12
2.2 返回前端字典
返回字典使用JsonResponse函數(shù)。 class JsonResponse(data,encoder = DjangoJSONEncoder,safe = True,json_dumps_params = None ,** kwargs)[source]1 JsonResponse是HttpResponse的一個(gè)子類(lèi),是Django提供的用于創(chuàng)建JSON編碼類(lèi)型響應(yīng)的快捷類(lèi)。 它從父類(lèi)繼承大部分行為,并具有以下不同點(diǎn): 它的默認(rèn)Content-Type頭部設(shè)置為application/json。 它的第一個(gè)參數(shù)data,通常應(yīng)該為一個(gè)字典數(shù)據(jù)類(lèi)型。 如果safe參數(shù)設(shè)置為False,則可以是任何可JSON 序列化的對(duì)象。 encoder默認(rèn)為django.core.serializers.json.DjangoJSONEncoder,用于序列化數(shù)據(jù)。 布爾類(lèi)型參數(shù)safe默認(rèn)為T(mén)rue。 如果設(shè)置為False,可以傳遞任何對(duì)象進(jìn)行序列化(否則,只允許dict 實(shí)例)。 from django.http import JsonResponsefrom .models import User,Diary
from django.forms.models import model_to_dict # 返回字典
def finduser(request):
??? userid = request.POST.get("userid", None)? # 讀取數(shù)據(jù)
??? users = User.objects.filter(id=userid)? # 獲取一個(gè)用戶,返回QuerySet
??? user = users[0]? # 獲取第一個(gè)user對(duì)象
??? user_dict1 = model_to_dict(user)? # 將對(duì)象轉(zhuǎn)化為字典
??? return JsonResponse(user_dict1)? # 返回前端字典1234567891011
2.3 返回?cái)?shù)據(jù)流
StreamingHttpResponse類(lèi)被用來(lái)從Django響應(yīng)一個(gè)流式對(duì)象到瀏覽器。如果生成的響應(yīng)太長(zhǎng)或者是占用的內(nèi)存較大,這么做可能更有效率。 例如,它對(duì)于生成大型的CSV文件非常有用。 StreamingHttpResponse不是HttpResponse的衍生類(lèi)(子類(lèi)),因?yàn)樗鼘?shí)現(xiàn)了完全不同的應(yīng)用程序接口。但是,除了幾個(gè)明顯不同的地方,兩者幾乎完全相同。2.4 返回文件
文件類(lèi)型響應(yīng)。通常用于給瀏覽器返回一個(gè)文件附件。 FileResponse是StreamingHttpResponse的衍生類(lèi),為二進(jìn)制文件專(zhuān)門(mén)做了優(yōu)化。 FileResponse需要通過(guò)二進(jìn)制模式打開(kāi)文件,如下: from django.http import FileResponseresponse = FileResponse(open('myfile.png', 'rb'))12
2.3 返回靜態(tài)html頁(yè)面
html文件被稱為視圖模板。如果需要返回html模板頁(yè)面,首先我們需要有一個(gè)html文件。我們需要在功能模塊app1文件夾下新建templates文件夾,用于存放html模板頁(yè)面。 我們?cè)趖emplates文件夾下創(chuàng)建一個(gè)insert.html模板。代碼如下 <!DOCTYPE html><html lang="en">
<head>
??? <meta charset="UTF-8">
??? <title>用戶登錄</title>
</head>
<body>
??? <form action="/app1/insert/" method="post">
??????? <input type="text" name="username"/>
??????? <input type="password" name="password"/>
??????? <input type="submit" value="提交">
??? </form>
</body>
</html>1234567891011121314 有了html文件,我們?cè)趘iews.py文件內(nèi)新建一個(gè)insertuser視圖函數(shù),返回這個(gè)模板頁(yè)面。 from django.shortcuts import render_to_response,redirect
from .models import User,Diary
import time
def insertuser(request):
??? return render_to_response('insert.html')? # 返回文件響應(yīng)1234567
? 其實(shí),python只是加載html文件,讀取內(nèi)容后,將內(nèi)容返回給前臺(tái)。所以是不是html格式并不重要。我們完全可以使用txt格式存儲(chǔ)。在views.py文件的函數(shù)中加載txt文件。
2.4 動(dòng)態(tài)生成html頁(yè)面
上面的模板文件只是靜態(tài)的html文件。在views視圖函數(shù)中是不能動(dòng)態(tài)修改的。如果我們想根據(jù)數(shù)據(jù)庫(kù)查詢結(jié)果動(dòng)態(tài)的修改模板頁(yè)面,形成新的頁(yè)面再返回給前端怎么辦? 我們把views中的函數(shù)用于邏輯處理,把處理結(jié)果交給html模板對(duì)象,來(lái)渲染成最終形成的html頁(yè)面。這個(gè)過(guò)程我們稱為渲染視圖。 我們?cè)趖emplates文件夾新建另一個(gè)html文件為showuser.html。內(nèi)容如下 <!DOCTYPE html><html lang="en">
<head>
??? <meta charset="UTF-8">
??? <title>Title</title>
</head>
<body>
??? <h1>信息展示</h1>
??? <table>
??? <tr>
??????? <th>用戶名</th>
??????? <th>密碼</th>
??? </tr>
??? {% for line in people_list %}
??? <tr>
??????? <td>{{line.username}}</td>
??????? <td>{{line.password}}</td>
??? </tr>
??? {% endfor %}
??? </table>
</body>
</html>12345678910111213141516171819202122 我們可以看到在html文件的代碼中包含了部分python代碼。至于則個(gè)動(dòng)態(tài)模板的書(shū)寫(xiě)規(guī)則以及如果使用view視圖函數(shù)傳遞的數(shù)據(jù)的, 我們?cè)诹硪黄恼聇emplates模板中再詳解。 不過(guò)這里我們需要知道在views視圖函數(shù)中如何向模板傳遞數(shù)據(jù)。 我們?cè)趘iews.py中實(shí)現(xiàn)findalluser函數(shù),代碼如下: from django.shortcuts import render_to_response
from .models import User,Diary # findalluser將數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù)讀出并展示出來(lái)。
def findalluser(request):
??? allpeople = User.objects.all()? # 查詢所有用戶
??? dict={
??????? 'people_list':allpeople
??? }
??? return render_to_response("showuser.html",dict)? # 返回文件響應(yīng),第二個(gè)參數(shù)必須為字典12345678910 視圖函數(shù)將數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù)讀出并結(jié)合html文件渲染出最后的響應(yīng)html源代碼。這和jsp中的原理相同,python先將html文件的內(nèi)容全部加載到內(nèi)存中, 再根據(jù)python的語(yǔ)法和傳來(lái)的數(shù)據(jù)庫(kù)數(shù)據(jù)生成html文件中python代碼部分產(chǎn)生的文本,再將最終生成的html源代碼返回到前端。 注意:在向模板傳遞參數(shù)時(shí)必須以字典的形式傳遞。
? 渲染的模板視圖生成的是html頁(yè)面,只能在瀏覽器中打開(kāi)。移動(dòng)互聯(lián)網(wǎng)下的移動(dòng)設(shè)備端是無(wú)法處理的。所以傳輸字典對(duì)象的形式更為流行。
三、render
上面學(xué)習(xí)了很多返回?cái)?shù)據(jù)類(lèi)型。在實(shí)際運(yùn)用中,加載模板、傳遞參數(shù),返回HttpResponse對(duì)象是一整套再常用不過(guò)的操作了,為了節(jié)省力氣,Django提供了一個(gè)快捷方式:render函數(shù),一步到位!
render方法可接收三個(gè)參數(shù),一是request參數(shù),二是待渲染的html模板文件,三是保存具體數(shù)據(jù)的字典參數(shù)。 它的作用就是將數(shù)據(jù)填充進(jìn)模板文件,最后把結(jié)果返回給瀏覽器。與jinja2類(lèi)似。 render(request, template_name, context=None, content_type=None, status=None, using=None)[source] 例如: def index(request): # 業(yè)務(wù)邏輯代碼 return render(request, "index.html", {"name": "monicx", "hobby": ["reading", "blog"]}) 結(jié)合一個(gè)給定的模板和一個(gè)給定的上下文字典,返回一個(gè)渲染后的HttpResponse對(duì)象。 必需參數(shù):request:視圖函數(shù)處理的當(dāng)前請(qǐng)求,封裝了請(qǐng)求頭的所有數(shù)據(jù),其實(shí)就是視圖參數(shù)request。
template_name:要使用的模板的完整名稱或者模板名稱的列表。如果是一個(gè)列表,將使用其中能夠查找到的第一個(gè)模板。
可選參數(shù):
context:添加到模板上下文的一個(gè)數(shù)據(jù)字典。默認(rèn)是一個(gè)空字典。可以將認(rèn)可需要提供給模板的數(shù)據(jù)以字典的格式添加進(jìn)去。這里有個(gè)小技巧,使用Python內(nèi)置的locals()方法,可以方便的將函數(shù)作用于內(nèi)的所有變量一次性添加。
content_type:用于生成的文檔的MIME類(lèi)型。 默認(rèn)為DEFAULT_CONTENT_TYPE設(shè)置的值。
status:響應(yīng)的狀態(tài)代碼。 默認(rèn)為200。
using:用于加載模板使用的模板引擎的NAME。
使用render可以同時(shí)處理請(qǐng)求對(duì)象request、html模板、數(shù)據(jù)庫(kù)數(shù)據(jù)。在Django中可以調(diào)用render函數(shù),也可以在模板對(duì)象上調(diào)用render函數(shù)。 1、調(diào)用全局render函數(shù)。看如下代碼: from django.shortcuts import render
from .models import User,Diary # findalluser將數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù)讀出并展示出來(lái)。
def findalluser(request):
??? allpeople = User.objects.all()? # 查詢所有用戶
??? dict={
??????? 'people_list':allpeople
??? }
??? return render(request,'showuser.html',dict)12345678910 render()函數(shù)的第一個(gè)位置參數(shù)是請(qǐng)求對(duì)象(就是view函數(shù)的第一個(gè)參數(shù)),第二個(gè)位置參數(shù)是模板。還可以有一個(gè)可選的第三參數(shù),一個(gè)字典,包含需要傳遞給模板的數(shù)據(jù)。最后render函數(shù)返回一個(gè)經(jīng)過(guò)字典數(shù)據(jù)渲染過(guò)的模板封裝而成的HttpResponse對(duì)象。 2、在template模板對(duì)象上調(diào)用render函數(shù)。如下示例 from django.shortcuts import render,HttpResponse def findalluser(request):
??? allpeople = models.User.objects.all()? # 查詢所有用戶
??? dict={
??????? 'people_list':allpeople
??? }
??? template = loader.get_template('showuser.html')? # 加載模板對(duì)象
??? return HttpResponse(template.render(dict1, request))? # 渲染視圖
四、redirect重定向
接受一個(gè)URL參數(shù),表示讓瀏覽器跳轉(zhuǎn)去指定的URL. 例如: def index(request): # 業(yè)務(wù)邏輯代碼 return redirect("https://blog.csdn.net/miaoqinian")轉(zhuǎn)載于:https://www.cnblogs.com/xibuhaohao/p/10192351.html
總結(jié)
以上是生活随笔為你收集整理的Python Django 前后端数据交互 之 HttpRequest、HttpResponse、render、redirect的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 铁路 12306 网站否认发生用户信息泄
- 下一篇: 2030年,逾1亿中国人需要学习新技能并