HttpResponse對象
視圖在接收請求并處理后,必須返回HttpResponse對象或子對象。在django.http模塊中定義了HttpResponse對象的API。HttpRequest對象由Django創(chuàng)建,HttpResponse對象由開發(fā)人員創(chuàng)建。
運行服務(wù)器,在瀏覽器中瀏覽首頁,可以在瀏覽器“開發(fā)者工具”中看到響應(yīng)信息如下圖:
標(biāo)號3為響應(yīng)頭信息,點擊標(biāo)號4處可以查看響應(yīng)體信息。

屬性
- content:表示返回的內(nèi)容。
- charset:表示response采用的編碼字符集,默認(rèn)為utf-8。
- status_code:返回的HTTP響應(yīng)狀態(tài)碼。
- content-type:指定返回數(shù)據(jù)的的MIME類型,默認(rèn)為'text/html'。
方法 - init:創(chuàng)建HttpResponse對象后完成返回內(nèi)容的初始化。
- set_cookie:設(shè)置Cookie信息。
set_cookie(key, value='', max_age=None, expires=None)
- cookie是網(wǎng)站以鍵值對格式存儲在瀏覽器中的一段純文本信息,用于實現(xiàn)用戶跟蹤。
- max_age是一個整數(shù),表示在指定秒數(shù)后過期。
- expires是一個datetime或timedelta對象,會話將在這個指定的日期/時間過期。
- max_age與expires二選一。
- 如果不指定過期時間,在關(guān)閉瀏覽器時cookie會過期。
- delete_cookie(key):刪除指定的key的Cookie,如果key不存在則什么也不發(fā)生。
- write:向響應(yīng)體中寫數(shù)據(jù)
示例
直接返回數(shù)據(jù)
1)打開booktest/views.py文件,定義視圖index2如下:
def index2(request):
str='<h1>hello world</h1>'
return HttpResponse(str)
2)打開booktest/urls.py文件,配置url。
url(r'^index2/$',views.index2),
3)運行服務(wù)器,在瀏覽器中打開如下網(wǎng)址。
http://127.0.0.1:8000/index2/
運行效果如下圖:

如果使用這種方式構(gòu)造一個漂亮豐富的頁面,對于開發(fā)人員真是會發(fā)瘋,于是就有了下面的方式:
調(diào)用模板
可以將html、css、js定義到一個html文件中,然后由視圖來調(diào)用。
1)打開booktest/views.py文件,定義視圖index3如下:
from django.template import RequestContext, loader
...
def index3(request):
#加載模板
t1=loader.get_template('booktest/index3.html')
#構(gòu)造上下文
context=RequestContext(request,{'h1':'hello'})
#使用上下文渲染模板,生成字符串后返回響應(yīng)對象
return HttpResponse(t1.render(context))
2)打開booktest/urls.py文件,配置url。
url(r'^index3/$',views.index3),
3)在templates/booktest/目錄下創(chuàng)建index3.html,代碼如下:
<html>
<head>
<title>使用模板</title>
</head>
<body>
<h1>{{h1}}</h1>
</body>
</html>
4)運行服務(wù)器,在瀏覽器中打開如下網(wǎng)址。
http://127.0.0.1:8000/index3/
運行效果如下圖:

調(diào)用模板簡寫函數(shù)render
每次調(diào)用模板時都要執(zhí)行加載、上下文、渲染三個步驟,為了簡化操作,Django定義了render()函數(shù)封裝了以上三個步驟的代碼,定義在django.shortcuts模塊中。
1)打開booktest/views.py文件,定義視圖index3如下
from django.shortcuts import render
...
def index3(request):
return render(request, 'booktest/index3.html', {'h1': 'hello'}
是不是用render()函數(shù)調(diào)用模板比上面簡單多了?
子類JsonResponse
在瀏覽器中使用javascript發(fā)起ajax請求時,返回json格式的數(shù)據(jù),此處以jquery的get()方法為例。類JsonResponse繼承自HttpResponse對象,被定義在django.http模塊中,創(chuàng)建對象時接收字典作為參數(shù)。
JsonResponse對象的content-type為'application/json'。
示例:Ajax登錄示例
打開test2/settings.py文件,在文件最底部,配置靜態(tài)文件查找路徑,并且要求開啟調(diào)試
DEBUG = True
...
STATIC_URL = '/static/'#pycharm創(chuàng)建的項目自帶這句,否則沒有這句
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
什么是 AJAX?
AJAX = 異步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
簡短地說,在不重載整個網(wǎng)頁的情況下,AJAX 通過后臺加載數(shù)據(jù),。對頁面進(jìn)行局的刷新,ajax請求都在后臺。并在網(wǎng)頁上進(jìn)行顯示

- 發(fā)起ajax請求:jquery發(fā)起
- 執(zhí)行相應(yīng)的視圖函數(shù),返回json內(nèi)容
- 執(zhí)行相應(yīng)的回調(diào)函數(shù)。通過判斷json內(nèi)容,進(jìn)行相應(yīng)處理。
Ajax登錄案例
- 首先分析出請求地址時需要攜帶的參數(shù)。
- 視圖函數(shù)處理完成之后,所返回的json的格式
Ajax登錄案例
- 首先分析出請求地址時需要攜帶的參數(shù)。
- 視圖函數(shù)處理完成之后,所返回的json的格式
1. 顯示出登錄頁面
a) 設(shè)計url,通過瀏覽器訪問 http://127.0.0.1:8000/login_show時顯示登錄頁面
b) 設(shè)計url對應(yīng)的視圖函數(shù)login_show。
c) 編寫模板文件login_ajax.html。在里面寫jquery代碼發(fā)起ajax請求
2.登錄校驗功能
a) 設(shè)計url,點擊登錄頁的登錄按鈕發(fā)起請求http://127.0.0.1:8000/login_ajax_check時進(jìn)行登錄校驗
b) 設(shè)計url對應(yīng)的視圖函數(shù)login_ajax_check。
接收post提交過來的數(shù)據(jù)。
進(jìn)行登錄校驗,并返回json內(nèi)容。 JsonRepsone
Json****格式如下:
{'res':'1'} #表示登錄成功
{'res':'0'} #表示登錄失敗
登錄頁面展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax登錄頁面</title>
</head>
<body>
用戶名:<input type="text" id="username"><br/>
密碼:<input type="password" id="password"><br/>
<input type="button" id="btnLogin" value="登錄">
<div id="errmsg"></div>
</body>
</html>
編寫登錄頁面視圖
url(r'^$', views.login_show),
def login_show(request):
return render(request, 'booktest/login.html')
當(dāng)點擊登錄時,就發(fā)起ajax請求,編寫login_ajax_check視圖
路由
url(r'^login_ajax_check/$', views.login_ajax_check),
視圖
def login_ajax_check(request):
# 1.獲取用戶名和密碼
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'sun' and password == '123':
# 用戶名密碼正確
return JsonResponse({'res':1})
# return redirect('/index') ajax請求在后臺,不要返回頁面或者重定向
else:
# 用戶名或密碼錯誤
return JsonResponse({'res':0})
編寫login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄界面</title>
{#導(dǎo)入jq#}
<script src="/static/js/jquery-1.12.4.min.js"> </script>
<script>
$(function () {
$('#btnLogin').click(function () {
{#1. 獲取用戶名和密碼#}
username = $('#username').val()
password = $('#password').val()
{#2. 發(fā)起ajax請求#}
$.ajax({
'url':'/login_ajax_check/',
'type': 'post',
'data':{'username':username,'password':password},
'dataType':'json'
}).success(
function (data) {
if (data.res == 0){
{#登陸失敗#}
$('#errmsg').show().html('用戶名或密碼錯誤')
}else{
{#跳轉(zhuǎn)到首頁#}
location.href='/'
}
}
)
})
})
</script>
<style>
#errmsg{
display: none;
color: red;
}
</style>
</head>
<body>
用戶名: <input type="text" id="username"><br/>
密碼: <input type="password" id="password"><br/>
<input type="button" id="btnLogin" value="登陸"><br/>
<div id="errmsg"></div>
</body>
</html>
ajax代碼執(zhí)行過程如下:
- 1.發(fā)起請求。
- 2.服務(wù)器端視圖函數(shù)執(zhí)行。
- 3.執(zhí)行回調(diào)函數(shù)。

子類HttpResponseRedirect
當(dāng)一個邏輯處理完成后,不需要向客戶端呈現(xiàn)數(shù)據(jù),而是轉(zhuǎn)回到其它頁面,如添加成功、修改成功、刪除成功后顯示數(shù)據(jù)列表,而數(shù)據(jù)的列表視圖已經(jīng)開發(fā)完成,此時不需要重新編寫列表的代碼,而是轉(zhuǎn)到這個視圖就可以,此時就需要模擬一個用戶請求的效果,從一個視圖轉(zhuǎn)到另外一個視圖,就稱為重定向。
Django中提供了HttpResponseRedirect對象實現(xiàn)重定向功能,這個類繼承自HttpResponse,被定義在django.http模塊中,返回的狀態(tài)碼為302。
示例
1)在booktest/views.py文件中定義視圖red1,代碼如下:
from django.http import HttpResponseRedirect
...
# 定義重定義向視圖,轉(zhuǎn)向首頁
def red1(request):
return HttpResponseRedirect('/')
2)在booktest/urls.py文件中配置url。
url(r'^red1/$', views.red1),
3)在地址欄中輸入網(wǎng)址如下:
http://127.0.0.1:8000/red1/
4)回車后,瀏覽器地址欄如下圖。

重定向簡寫函數(shù)redirect
在django.shortcuts模塊中為重定向類提供了簡寫函數(shù)redirect。
1)修改booktest/views.py文件中red1視圖,代碼如下:
from django.shortcuts import redirect
...
def red1(request):
return redirect('/')
<meta charset="utf-8">
狀態(tài)保持
瀏覽器請求服務(wù)器是無狀態(tài)的。無狀態(tài)指一次用戶請求時,瀏覽器、服務(wù)器無法知道之前這個用戶做過什么,每次請求都是一次新的請求。無狀態(tài)的應(yīng)用層面的原因是:瀏覽器和服務(wù)器之間的通信都遵守HTTP協(xié)議。根本原因是:瀏覽器與服務(wù)器是使用Socket套接字進(jìn)行通信的,服務(wù)器將請求結(jié)果返回給瀏覽器之后,會關(guān)閉當(dāng)前的Socket連接,而且服務(wù)器也會在處理頁面完畢之后銷毀頁面對象。
有時需要保存下來用戶瀏覽的狀態(tài),比如用戶是否登錄過,瀏覽過哪些商品等。 實現(xiàn)狀態(tài)保持主要有兩種方式:
在客戶端存儲信息使用Cookie。
在服務(wù)器端存儲信息使用Session。
Cookie
Cookie,有時也用其復(fù)數(shù)形式Cookies,指某些網(wǎng)站為了辨別用戶身份、進(jìn)行session跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。Cookie最早是網(wǎng)景公司的前雇員Lou Montulli在1993年3月的發(fā)明。Cookie是由服務(wù)器端生成,發(fā)送給User-Agent(一般是瀏覽器),瀏覽器會將Cookie的key/value保存到某個目錄下的文本文件內(nèi),下次請求同一網(wǎng)站時就發(fā)送該Cookie給服務(wù)器(前提是瀏覽器設(shè)置為啟用cookie)。Cookie名稱和值可以由服務(wù)器端開發(fā)自己定義,這樣服務(wù)器可以知道該用戶是否是合法用戶以及是否需要重新登錄等。服務(wù)器可以利用Cookies包含信息的任意性來篩選并經(jīng)常性維護這些信息,以判斷在HTTP傳輸中的狀態(tài)。Cookies最典型記住用戶名。
Cookie是存儲在瀏覽器中的一段純文本信息,建議不要存儲敏感信息如密碼,因為電腦上的瀏覽器可能被其它人使用。
Cookie的特點
- Cookie以鍵值對的格式進(jìn)行信息的存儲。
- Cookie基于域名安全,不同域名的Cookie是不能互相訪問的,如訪問neuedu.cn時向瀏覽器中寫了Cookie信息,使用同一瀏覽器訪問baidu.com時,無法訪問到neuedu.cn寫的Cookie信息。
- 當(dāng)瀏覽器請求某網(wǎng)站時,會將瀏覽器存儲的跟網(wǎng)站相關(guān)的所有Cookie信息提交給網(wǎng)站服務(wù)器。
典型應(yīng)用:記住用戶名,網(wǎng)站的廣告推送。
說明:這些廣告推送的商品是基于你曾經(jīng)在淘寶上點擊的商品類別等條件篩選出來的,看上去這是在鳳凰網(wǎng)上訪問淘寶網(wǎng)的Cookie,但是事實不是這樣的,一般是采用iframe標(biāo)簽嵌套一個淘寶的廣告頁面到鳳凰網(wǎng)的頁面上,所以淘寶的Cookie并沒有被鳳凰網(wǎng)讀取到,而是依然交給淘寶網(wǎng)讀取的,可以通過"開發(fā)者工具"查看元素,如下圖

接下來講解如何在Django中實現(xiàn)Cookie的讀寫。
設(shè)置Cookie
1)打開booktest/views.py文件,創(chuàng)建視圖cookie_set。
def cookie_set(request):
response = HttpResponse("<h1>設(shè)置Cookie,請查看響應(yīng)報文頭</h1>")
response.set_cookie('h1', bytes('你好', 'utf-8').decode('ISO-8859-1'))
return response
2)打開booktest/urls.py文件,配置url。
url(r'^cookie_set/$',views.cookie_set),
3)在瀏覽器輸入如下網(wǎng)址。
http://127.0.0.1:8000/cookie_set/
在"開發(fā)者工具"中可以在響應(yīng)頭中查看到設(shè)置的Cookie信息。

讀取Cookie
Cookie信息被包含在請求頭中,使用request對象的COOKIES屬性訪問。
1)打開booktest/views.py文件,創(chuàng)建視圖cookie_get。
def cookie_get(request):
response = HttpResponse("讀取Cookie,數(shù)據(jù)如下:<br>")
if 'h1' in request.COOKIES:
response.write('<h1>' + request.COOKIES['h1'].encode("iso-8859-1").decode('utf8') + '</h1>')
return response
2)打開booktest/urls.py文件,配置url。
url(r'^cookie_get/$',views.cookie_get),
3)在瀏覽器輸入如下網(wǎng)址。
http://127.0.0.1:8000/cookie_get/
4)打開“開發(fā)者工具”,在請求頭中可以查看Cookie信息,瀏覽效果如下圖:

Session
對于敏感、重要的信息,建議要儲在服務(wù)器端,不能存儲在瀏覽器中,如用戶名、余額、等級、驗證碼等信息。
在服務(wù)器端進(jìn)行狀態(tài)保持的方案就是Session。
啟用Session
Django項目默認(rèn)啟用Session。
打開test3/settings.py文件,在項MIDDLEWARE_CLASSES中啟用Session中間件。

禁用Session:將Session中間件刪除。
如果存儲在數(shù)據(jù)庫中,需要在項INSTALLED_APPS中pycharm已經(jīng)默認(rèn)添加了Session應(yīng)用。

示例
寫session
1)打開booktest/views.py文件,創(chuàng)建視圖session_test,代碼如下:
def session_test(request):
request.session['h1']='hello'
return HttpResponse('寫入session')
2)打開booktest/urls.py文件,配置url。
url(r'^session_test/$',views.session_test),
3)運行服務(wù)器,打開瀏覽器請求如下網(wǎng)址。
http://127.0.0.1:8000/session_test/
4)瀏覽效果如下圖,在"開發(fā)者工具"中可以查看到響應(yīng)頭中創(chuàng)建了Cookie,里面有個鍵為sessionid。
