1. 程式人生 > >python---django請求-響應的生命周期(FBV和CBV含義)

python---django請求-響應的生命周期(FBV和CBV含義)

ike code getattr take err now() asa ted 圖片

Django請求的生命周期是指:當用戶在訪問該url路徑是,在服務器Django後臺都發生了什麽。

客戶端發送Http請求給服務端,Http請求是一堆字符串,其內容是:技術分享圖片

訪問:http://crm.oldboy.com:8080/login.html,客戶端發送Http請求

1.路由映射,匹配路由(從上到下,匹配到就停止),對應相應views中的業務函數

url(r^login.html, views.login),

2.匹配成功後,執行views下的對應函數:(FBV)

技術分享圖片
def login(req):
    print(req.body,req.body)
    print("GET
",req.GET) message=‘‘ if req.method == "POST": print(req.body) print(req.POST) user = req.POST.get("username") pwd = req.POST.get("password") count = models.Administrator.objects.filter(username=user,password=pwd).count() if count: red
= redirect("/index.html") timeout = datetime.datetime.now()+datetime.timedelta(seconds=3) red.set_cookie(username,user,expires=timeout) return red else: message = "用戶名或密碼錯誤" return render(req,"login.html",{msg:message})
View Code
URL -->  函數  ====>  FBV(Function-based views)    基於函數的視圖
URL -->  類    ====> CBV (Class-based views)    基於類的視圖

FBV:在Django中使用較多,在其他框架中多使用CBV,例如tornado,還有PHP的多種框架等

Django中CBV使用:

首先需要設置views中的類:

from django.views import View
class CBV(View):
   #根據請求頭中的request method進行自動執行get和post def
get(self,request): return render(request,"cbv_login.html") def post(self,request): return HttpResponse("<h1>cbv_post</h1>")

然後修改urls文件路由:

urlpatterns = [
    url(r"cbv",views.CBV.as_view())
]

模板文件:

技術分享圖片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/cbv" method="post">
    {% csrf_token %}
    <div>
        <label for="user">用戶名:</label>
        <input type="text" id="user" name="username"/>
    </div>
    <div>
        <label for="pwd">密碼:</label>
        <input type="password" id="pwd" name="password"/>
    </div>
    <div>
        <label></label>
        <input type="submit" value="登錄">
        <label>{{ msg }}</label>
    </div>
</form>
</body>
</html>
cbv_login.html

使用url訪問默認是get方式,顯示cbv_login.html頁面,提交頁面,進入post頁面,顯示cbv_post數據

get還是post,是由於請求頭中的Request Method:獲取,從而找到對應方法。使用反射查找,來執行對應方法。

1.由Request URL請求去獲取路徑,與urls進行匹配,找到對應的類
2.由請求體得到:Request Method:GET
3.獲得類中方法
   方法名  =  getattr(對象,"GET")
   方法名()    #執行對應函數

源碼查看:

@classonlymethod
    def as_view(cls, **initkwargs):
        """
        Main entry point for a request-response process.請求-響應的主入口點,在url解析時調用
        """
     for key in initkwargs:
     #cls.http_method_names:
     #[u‘get‘, u‘post‘, u‘put‘, u‘patch‘, u‘delete‘, u‘head‘, u‘options‘, u‘trace‘]
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don‘t do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))
        #print(cls)  #<class ‘app1.views.CBV‘>
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)  #實例化CBV對象
            if hasattr(self, get) and not hasattr(self, head):
                self.head = self.get
            self.request = request
            #print(request)    <WSGIRequest: GET ‘/cbv‘>
            #print(request.method)  GET
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)#調用dispatch方法,將<WSGIRequest: GET ‘/cbv‘>傳入
        view.view_class = cls
        view.view_initkwargs = initkwargs

        # take name and docstring from class
        update_wrapper(view, cls, updated=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())
        return view

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesnt exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isnt on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed) #去調用對應的函數
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

推薦:介紹——基於類的視圖(class-based view)

3.業務處理

-----根據個人需求自定義

-----對於框架:基本操作是操作數據庫

  ---pymysql (原生)

  ---SQLAlchemy

  ---Django中orm

-----響應內容:返回給用戶的結果:響應頭和響應體

我們寫的HTTPResponse是寫在響應體中

響應頭的定制:

    def post(self,request):
        ret =  HttpResponse("<h1>post</h1>")
     #下面為設置請求頭 ret[
‘h1‘] =‘v1‘ ret.set_cookie(‘c1‘,‘v1‘) ret.set_cookie(‘c2‘,‘v2‘) ‘‘‘ 響應頭:h1=v1 cookies:c1=v1;c2=v2 響應體:<h1>post</h1> 請求頭信息: Content-Length:13 Content-Type:text/html; charset=utf-8 Date:Wed, 28 Mar 2018 13:54:53 GMT h1:v1 Server:WSGIServer/0.1 Python/2.7.10 Set-Cookie:c2=v2; Path=/ Set-Cookie:c1=v1; Path=/ X-Frame-Options:SAMEORIGIN ‘‘‘ return ret

python---django請求-響應的生命周期(FBV和CBV含義)