[toc]
1 概述
1.1 視圖作用
視圖接受web請求,并響應(yīng)web請求;
1.2 視圖本質(zhì)
視圖就是一個python中的函數(shù);
1.3 響應(yīng)的內(nèi)容
網(wǎng)頁
重定向
錯誤視圖 400、404、500
JSON數(shù)據(jù)
1.4 響應(yīng)的過程
graph LR
A[<b>用戶在瀏覽器輸入網(wǎng)址</b><br>www.class.com/grade/index.html<br><br><b><i>網(wǎng)址</i></b>] --> B
B[<b>django獲取網(wǎng)址信息</b><br>去除ip與端口<br>grade/index.html<br><br><b><i>虛擬路徑與文件名</i></b>] --> C
C[<b>url管理器</b><br>逐個匹配urlconf<br>記錄視圖函數(shù)名<br><br><b><i>視圖函數(shù)名</i></b>] --> D
D[<b>視圖管理器</b><br>找到對應(yīng)的視圖去執(zhí)行<br>返回結(jié)果給瀏覽器<br><br><b><i>響應(yīng)的數(shù)據(jù)</i></b>] --> A
2 url配置
2.1 配置流程
1. 指定根級url配置文件
配置 settings.py 文件中的 ROOT_URLCONF
ROOT_URLCONF = 'class.urls'
django默認(rèn)配置好了
2. urlpatterns
一個url實例列表
url對象:
正則表達(dá)式
視圖名稱
名稱
3. url匹配正則的注意事項
如果想要從url中獲取一個值,需要對正則加小括號
url(r'^stupage/(\d)/$', views.stupage),
匹配正則前方不需要加 /
正則前需要加 r 表示字符串不轉(zhuǎn)義
2.2 引入其他url配置
在應(yīng)用中創(chuàng)建 urls.py 配置文件,定義本應(yīng)用的url配置,在 工程/urls.py 文件中使用include()方法
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^', include('myapp.urls', namespace='myapp'))
]
匹配過程:
工程/urls.py --> 應(yīng)用/urls.py
2.3 URL的反向解析
namespace='myapp'
name='myapp'
情景:
如果修改了urls.py 中的正則表達(dá)式,則對應(yīng)的模板中的 鏈接也都要做對應(yīng)修改,非常影響工作;
概述:
如果在視圖、模板中使用了硬編碼鏈接,在url配置發(fā)生改變時,動態(tài)生成鏈接地址;
解決:
在使用鏈接時,通過url配置的名稱,動態(tài)生成url地址;
作用:
使用url模板
3 視圖函數(shù)
3.1 定義視圖
本質(zhì):
一個函數(shù);
視圖參數(shù):
一個HttpRequest的實例,里面包含來自瀏覽器的全部內(nèi)容;
通過正則表達(dá)式獲取的參數(shù);
位置:
一般在views.py文件下定義;
3.2 錯誤視圖
400視圖 錯誤出現(xiàn)在客戶的操作
500視圖 在視圖代碼中出現(xiàn)錯誤(服務(wù)器代碼)
404視圖
找不到網(wǎng)頁(url匹配不成功)時返回
在template下定義404.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>頁面丟失</h1>
<h2>{{ request_path }}</h2>
</body>
</html>
#------------------------------------
request_path 導(dǎo)致錯誤的網(wǎng)址
配置settings.py
DEBUG 如果為True,永遠(yuǎn)不會調(diào)用404.html
ALLOWED_HOSTS = ['*']
4 HttpRequest對象
4.1 概述
服務(wù)器接受http請求后,會根據(jù)報文創(chuàng)建一個HttpRequest對象;
視圖的第一個參數(shù)就是 HttpRequest 對象;
Django創(chuàng)建的對象,之后傳遞給視圖;
4.2 屬性
path
請求的完整路徑(不包括域名和端口);
method
表示請求的方式,常用的有GET、POST;
encoding
表示瀏覽器提交的數(shù)據(jù)的編碼方式;
一般為utf-8;
GET
類似字典的對象,包含了get請求的所有參數(shù);
POST
類似字典的對象,包含了post請求的所有參數(shù);
FILES
類似字典的對象,包含了所有上傳的文件;
COOKIES
字典,包含所有的cookie
session
類似字典的對象,表示當(dāng)前的會話;
4.3 方法
is_ajax()
如果是通過XMLHttpRequest發(fā)起的,返回True;
4.4 QueryDict對象
request對象中的GET、POST都屬于QueryDict對象;
方法:
get()
作用:根據(jù)鍵獲取值
只能獲取一個值
www.class.com/abc?a=1&b=2&c=3 有一個a
getlist()
將鍵的值以列表的形式返回
可以獲取多個值
www.class.com/abc?a=1&a=2&c=3 有兩個a
4.5 GET屬性
獲取瀏覽器傳遞給服務(wù)器的數(shù)據(jù);
http://127.0.0.1:8000/get1?a=1&b=2&c=3
def get1(request):
a = request.GET.get('a')
b = request.GET.get('b')
c = request.GET.get('c')
return HttpResponse(a + '|' + b + '|'+ c)
http://127.0.0.1:8000/get2?a=1&a=2&c=3
def get2(request):
a = request.GET.getlist('a')
a1 = a[0]
a2 = a[1]
c = request.GET.get('c')
return HttpResponse(a1 + '|' + a2 + '|' + c)
4.6 POST屬性
使用表單
編輯一個表單模板 register.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注冊</title>
</head>
<body>
<form action="register/" method="post">
姓名:
<input type="text" name="name" value="">
<hr>
性別:
<input type="radio" name="gender" value="1">男
<input type="radio" name="gender" value="10">女
<hr>
年齡:
<input type="text" name="age" value="">
<hr>
愛好:
<input type="checkbox" name="hobby" value="power">權(quán)利
<input type="checkbox" name="hobby" value="money">金錢
<input type="checkbox" name="hobby" value="boy">美男
<input type="checkbox" name="hobby" value="girl">美女
<hr>
<input type="submit", value="注冊">
</form>
</body>
</html>
編輯urls.py:
url(r'^showregister/$', views.showregister),
url(r'^showregister/register/$', views.register),
編輯視圖 views.py:
def showregister(request):
return render(request, 'myapp/register.html')
def register(request):
name = request.POST.get('name')
gender = request.POST.get('gender')
age = request.POST.get('age')
hobby = request.POST.getlist('hobby')
print(name)
print(gender)
print(age)
print(hobby)
return HttpResponse('resgister')
關(guān)閉CSRF
注釋掉 settings.py 中的 MIDDLEWARE: 'django.middleware.csrf.CsrfViewMiddleware'
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
5 HttpResponse對象
5.1 概述
作用:
給瀏覽器返回數(shù)據(jù);
HttpRequest對象是由Django創(chuàng)建的,HttpResponse對象是有程序員創(chuàng)建的
5.2 返回用法
不調(diào)用模板,直接返回數(shù)據(jù)
def index(request):
return HttpResponse('Hahahahaha')
調(diào)用模板,使用 render() 方法:
原型:
render(request, templateName[, context])
作用:
結(jié)合數(shù)據(jù)和模板,返回完整的HTML頁面;
參數(shù):
request 請求對象體
templateName 模板路徑
context 傳遞給需要渲染在模板的數(shù)據(jù)
示例:
def grade(request):
gradeList = Grade.objects.all()
return render(request, 'myapp/grade.html', {'grade': gradeList})
5.3 屬性
content
表示返回的內(nèi)容的類型
character
返回的數(shù)據(jù)的編碼格式
status_code
響應(yīng)狀態(tài)碼
200
304
404
content-tpye
指定輸出的MIME類型
栗子:
url(r'^showresponse/$', views.showresponse),
def showresponse(request):
res = HttpResponse()
res.content = b'nice'
print(res.content)
print(res.charset)
print(res.status_code)
print(res.content-type)
return res
5.4 方法
init
使用頁面內(nèi)容實例化HttpResponse對象
writr(content)
以文件的形式寫入
flush
以文件的形式輸出緩沖區(qū)
set_cookie(key, value, max_age=None, exprise=None)
delete_cookie(key)
刪除 cookie
注意: 如果刪除一個不存在的cookie,什么都不會發(fā)生;
栗子:
url(r'^cookietest/$', views.cookietest)
def cookietest(request):
res = HttpResponse()
# res.set_cookie("class", "good")
cookie = request.COOKIES
res.write("<h1>" + cookie['class'] + "</h1>")
return res
5.5 子類 HttpResponseRedirect
功能:
重定向,服務(wù)器端的跳轉(zhuǎn);
栗子:
url(r'^redirect1/$', views.redirect1),
url(r'^redirect2/$', views.redirect2),
from django.http import HttpResponseRedirect
def redirect1(request):
print('我是重定向前的redirect1')
return HttpResponseRedirect('/redirect2')
def redirect2(request):
return HttpResponse('我是重定向后的redirect2')
簡寫: redirect(to) to 推薦使用反向解析
from django.shortcuts import redirect
def redirect1(request):
print('我是重定向前的redirect1')
return redirect('/redirect2')
def redirect2(request):
return HttpResponse('我是重定向后的redirect2')
5.6 子類 JsonResponse
返回json數(shù)據(jù),一般用于異步請求(ajax)
__init__(self, data)
data 字典對象
注意:
Content-type 類型為 application/json
6 狀態(tài)保持 session
6.1 概述
HTTP協(xié)議是無狀態(tài)的,每次請求都是一次新的請求,不記得以前的請求;
客戶端與服務(wù)器端的一次通信就是一次會話;
實現(xiàn)狀態(tài)保持,在客戶端或者服務(wù)器端存儲有關(guān)會話數(shù)據(jù);
存儲的方式:
cookie 所有的數(shù)據(jù)都存儲在客戶端,不要存儲敏感數(shù)據(jù);
session 所有的數(shù)據(jù)存儲在服務(wù)端,在客戶端用cookie存儲session_id;
狀態(tài)保持的目的:
在一段時間內(nèi),跟蹤請求者的狀態(tài),可以實現(xiàn)跨頁面訪問當(dāng)前請求者的數(shù)據(jù);
注意:
不同的請求者之間不會共享這個數(shù)據(jù);
6.2 啟用session
settings.py中:
INSTALLED_APPS
'django.contrib.sessions',
MIDDLEWARE
'django.contrib.sessions.middleware.SessionMiddleware',
默認(rèn)啟用
6.3 使用session
啟用session后,每個HttpRequest對象,都有一個session屬性,就是一個類似字典的對象;
get(key, default=None)
根據(jù)鍵獲取session值
clear()
清空所有的會話
flush()
刪除當(dāng)前的會話并刪除會話的cookie
栗子:
歡迎頁 --登錄--> 登錄頁 --輸入用戶名--> 歡迎頁,顯示登錄名
歡迎頁 --退出登錄--> 清理session
urls.py
url(r'^main/$', views.main),
url(r'^login/$', views.login),
url(r'^showmain/$', views.showmain),
url(r'^quit/$', views.quit),
views.py
from django.shortcuts import redirect
def main(request):
# 取session
username = request.session.get('name', '游客')
return render(request, 'myapp/main.html', {"username": username})
def login(request):
return render(request, 'myapp/login.html')
def showmain(request):
username = request.POST.get('username')
# 存儲session
request.session['name'] = username
return redirect('/main')
from django.contrib.auth import logout
def quit(request):
# 清除session
# logout(request)
request.session.clear()
return redirect('/main')
main.html
<head>
<meta charset="UTF-8">
<title>我的</title>
</head>
<body>
<h1>歡迎:{{ username }}</h1>
<a href="/login/">登錄</a>
<a href="/quit/">退出登錄</a>
</body>
login.html
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<form action="/showmain/" method="post">
<input type="text" name="username"><br>
<input type="submit" value="登錄">
</form>
</body>
6.4 設(shè)置過期時間
set_expiry(value)
如果不設(shè)置,默認(rèn)是兩個星期后過期;
整數(shù):
value填10,則是10秒后過期;
def showmain(request):
username = request.POST.get('username')
# 存儲session
request.session['name'] = username
request.session.set_expiry(10)
return redirect('/main')
時間對象
0
關(guān)閉瀏覽器是失效
None
永不過期
6.5 存儲session的位置
在 settings.py 中增加 SESSION_ENGINE 配置;
數(shù)據(jù)庫
默認(rèn)存儲在數(shù)據(jù)庫中;
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
緩存
只存出在本地內(nèi)存中,如果丟失,不能找回;
SESSION_ENGINE = 'django.contrib.sessions.backends.cached'
數(shù)據(jù)庫和緩存
優(yōu)先從本地緩存中讀取,讀取不到,再去數(shù)據(jù)庫中獲取;
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
6.6 使用redis緩存session
pip install django-redis-session
配置redis:
在settings.py追加:
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = 'admin'
SESSION_REDIS_PREFIX = 'session'