Django中請求的生命周期
1. 概述
首先我們知道HTTP請求及服務端回應中傳輸的所有資料都是字串.
在Django中,當我們訪問一個的url時,會通過路由匹配進入相應的html網頁中.
Django的請求生命周期是指當用戶在瀏覽器上輸入url到用戶看到網頁的這個時間段內,Django后臺所發生的事情
而Django的生命周期內到底發生了什么呢??
1. 當用戶在瀏覽器中輸入url時,瀏覽器會生成請求頭和請求體發給服務端
請求頭和請求體中會包含瀏覽器的動作(action),這個動作通常為get或者post,體現在url之中.
2. url經過Django中的wsgi,再經過Django的中間件,最后url到過路由映射表,在路由中一條一條進行匹配,
一旦其中一條匹配成功就執行對應的視圖函式,后面的路由就不再繼續匹配了.
3. 視圖函式根據客戶端的請求查詢相應的資料.回傳給Django,然后Django把客戶端想要的資料做為一個字串回傳給客戶端.
4. 客戶端瀏覽器接收到回傳的資料,經過渲染后顯示給用戶.
視圖函式根據客戶端的請求查詢相應的資料后.如果同時有多個客戶端同時發送不同的url到服務端請求資料
服務端查詢到資料后,怎么知道要把哪些資料回傳給哪個客戶端呢??
因此客戶端發到服務端的url中還必須要包含所要請求的資料資訊等內容.
例如,http://www.aaa.com/index/?nid=user這個url中,
客戶端通過get請求向服務端發送的nid=user的請求,服務端可以通過request.GET.get("nid")的方式取得nid資料
客戶端還可以通過post的方式向服務端請求資料.
當客戶端以post的方式向服務端請求資料的時候,請求的資料包含在請求體里,這時服務端就使用request.POST的方式取得客戶端想要取得的資料
需要注意的是,request.POST是把請求體的資料轉換一個字典,請求體中的資料默認是以字串的形式存在的.
2. FBV模式和CBV模式
一個url對應一個視圖函式,這個模式叫做FBV(Function Base Views)
除了FBV之處,Django中還有另外一種模式叫做CBV(Class Base views),即一個url對應一個類
例子:使用cbv模式來請求網頁
路由資訊:
urlpatterns = [
url(r'^fbv/',views.fbv),
url(r'^cbv/',views.CBV.as_view()),
]
視圖函式配置:
from django.views import View
class CBV(View):
def get(self,request):
return render(request, "cbv.html")
def post(self,request):
return HttpResponse("cbv.get")
cbv.html網頁的內容:
<body>
<form method="post" action="/cbv/">
{% csrf_token %}
<input type="text">
<input type="submit">
</form>
</body>
啟動專案,在瀏覽器中輸入http://127.0.0.1:8000/cbv/,回車,得到的網頁如下:

在input框中輸入"hello",后回車,得到的網頁如下:

使用fbv的模式,在url匹配成功之后,會直接執行對應的視圖函式.
而如果使用cbv模式,在url匹配成功之后,會找到視圖函式中對應的類,然后這個類回到請求頭中找到對應的Request Method.
如果是客戶端以post的方式提交請求,就執行類中的post方法;
如果是客戶端以get的方式提交請求,就執行類中的get方法
然后查找用戶發過來的url,然后在類中執行對應的方法查詢生成用戶需要的資料.
2.1 fbv方式請求的程序
用戶發送url請求,Django會依次遍歷路由映射表中的所有記錄,一旦路由映射表其中的一條匹配成功了,
就執行視圖函式中對應的函式名,這是fbv的執行流程
2.2 cbv方式請求的程序
當服務端使用cbv模式的時候,用戶發給服務端的請求包含url和method,這兩個資訊都是字串型別
服務端通過路由映射表匹配成功后會自動去找dispatch方法,然后Django會通過dispatch反射的方式找到類中對應的方法并執行
類中的方法執行完畢之后,會把客戶端想要的資料回傳給dispatch方法,由dispatch方法把資料回傳經客戶端
例子,把上面的例子中的視圖函式修改成如下:
from django.views import View
class CBV(View):
def dispatch(self, request, *args, **kwargs):
print("dispatch......")
res=super(CBV,self).dispatch(request,*args,**kwargs)
return res
def get(self,request):
return render(request, "cbv.html")
def post(self,request):
return HttpResponse("cbv.get")
列印結果:
<HttpResponse status_code=200, "text/html; charset=utf-8">
dispatch......
<HttpResponse status_code=200, "text/html; charset=utf-8">
需要注意的是:
以get方式請求資料時,請求頭里有資訊,請求體里沒有資料
以post請求資料時,請求頭和請求體里都有資料.
3. Django請求生命周期之回應內容
http提交資料的方式有"post","get","put","patch","delete","head","options","trace".
提交資料的時候,服務端依據method的不同會觸發不同的視圖函式.
對于from表單來說,提交資料只有get和post兩種方法
另外的方法可以通過Ajax方法來提交
服務端根據個人請求資訊的不同來操作資料庫,可以使用原生的SQL陳述句,也可以使用Django的ORM陳述句.
Django從資料庫中查詢處理完用戶想要的資料,將結果回傳給用戶.
從Django中回傳的回應內容包含回應頭和回應體
在Django中,有的時候一個視圖函式,執行完成后會使用HttpResponse來回傳一個字串給客戶端.
這個字串只是回應體的部分,回傳給客戶端的回應頭的部分應該怎么設定呢???
為回傳給客戶端的資訊加一個回應頭:
修改上面例子的視圖函式為如下:
from django.views import View
class CBV(View):
def dispatch(self, request, *args, **kwargs):
print("dispatch......")
res=super(CBV,self).dispatch(request,*args,**kwargs)
print(res)
return res
def get(self,request):
return render(request, "cbv.html")
def post(self,request):
res=HttpResponse("cbv.post")
res.set_cookie("k2","v2")
res.set_cookie("k4","v4")
print("res:",res)
print("request.cookie:",request.COOKIES)
return res
列印的資訊:
res: <HttpResponse status_code=200, "text/html; charset=utf-8">
request.cookie: {'csrftoken': 'jmX9H1455MYzDRQs8cQLrA23K0aCGoHpINL50GnMVxhUjamI8wgmOP7D2wXcpjHb', 'k2': 'v2', 'k4': 'v4'}
視圖層
1. HTTP請求
HttpRequest物件
request.path #使用GET方法時,只會得到路徑,
request.get_full_path() #使用GET方法時,會得到包括路徑和?,=等資訊的全路徑
request.method #客戶端請求網頁的HTTP方法:POST或GET
request.GET #包含所有HTTP請求的GET方法的類字典物件
request.POST #包含所有HTTP請求的POST方法的類字典物件
request.COOkIES #包含cookies的字典物件,其鍵和值都是字串
request.sessions #唯一可讀寫的類字典物件,表示與服務端的當前會話資訊
request.body #POST原始資料,用于對資料的復雜處理
request.has_key() #布林值,標識request.GET或request.POST是否包含指定的鍵
request.is_secure() #客戶端發出的請求是否安全
request.user #代表當前登錄的用戶的django.contrib.auth.models.User物件
request.FILES #通過表單上傳的檔案的類字典物件
|--> request.FILES.get('filename') #上傳檔案的檔案名
|--> request.FILES.get('content_type') #上傳檔案的內容原型
|--> request.FILES.get('content') #上傳檔案的原始內容
META #一個包含所有有效的HTTP頭資訊的字典
|--> content_length #所接收的資料的長度
|--> content_type #所接收的資料的型別
|--> query_string #接收的原始請求字串
|--> remote_addr #客戶端的IP地址
|--> remote_host #客戶端的主機名稱
|--> remote_name #服務端的主機名
|--> remote_port #服務端的埠號
|--> http_host #客戶端發送的HOST頭部資訊
|--> http_referer #被指向的頁面
|--> http_user_agent #客戶端使用的瀏覽器的資訊
|--> http_x_bender #X_bender頭資訊
2. HTTP回應
HttpResponse物件
locals() #把視圖函式中所有的變數傳給模板
# 方法:
redirect() #重定向方法,跳轉到另一個頁面
HttpResponse() #回傳一個字串給客戶端
render()
|--> template_name # 必選引數 模板名字
|--> context # 可選引數 開發人員可以添加一個字典資訊到模板中,用來提示用戶,默認是一個空字典
|--> content_type # 可選引數 MIME型別用于生成檔案
|--> status # 可選引數 回應狀態代碼,默認值200
|--> useing # 可選引數 用于加載模板的模板引擎的名稱
路由
#單一路由分配
url(r"^index$",views.index)
#基于正則的路由分配
url(r"^index/(\d*)",views.index)
url(r"^index/(?P<name>\w)/(?<id>\d)",views.index)
#添加額外的引數
url(r"^manage/(?P<name>\w)",views.manage,["id":333])
#路由映射設定名稱
url(r"^home",views.home,name="h1")
url(r"^index/(\d)",views.home,name="h2")
#路由分支
url(r"^blog/",include("blog.urls"))
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/137702.html
標籤:Python
