天天看點

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/

,回車,得到的網頁如下:

Django中請求的生命周期

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

Django中請求的生命周期

使用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'}