• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • python_fullstack—Django框架(十一)-Django MiddleWare初識

    標簽: Django

    Django MiddleWare初識

    一、Django 中間件介紹

    • 中間件是一個用來處理Django的請求和響應的框架級別的鉤子。它是一個輕量、低級別的插件系統,用于在全局范圍內改變Django的輸入和輸出。每個中間件組件都負責做一些特定的功能。
    • 簡而言之中間件是幫助我們在視圖函數執行之前和執行之后都可以做一些額外的操作,它本質上就是一個自定義類,類中定義了幾個方法,Django框架會在請求的特定的時間去執行這些方法。
    • Django的中間件在settings.py中配置,MIDDLEWARE配置項是一個列表,列表中是一個個字符串,這些字符串其實是一個個類,也就是一個個中間件。
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    二、中間件執行流程梳理

    1、核心方法介紹

    • 中間件核心的包括五個方法,分別是:
      • process_request(self,request)
      • process_view(self, request, view_func, view_args, view_kwargs)
      • process_template_response(self,request,response)
      • process_exception(self, request, exception)
      • process_response(self, request, response)

    以上方法的返回值可以是None或一個HttpResponse對象,如果是None,則繼續按照django定義的規則向后繼續執行,如果是HttpResponse對象,則直接將該對象返回給用戶。

    1.1、process_request(self, request)

    • process_request有一個參數request,這個request和視圖函數中的request是一樣的。
    • 它的返回值可以是None也可以是HttpResponse對象。返回值是None的話,按正常流程繼續走,交給下一個中間件處理,如果是HttpResponse對象,Django將不執行視圖函數,而將相應對象返回給瀏覽器。

    • 總結一下:

      • 中間件的process_request方法是在執行視圖函數之前執行的。
      • 當配置多個中間件時,會按照MIDDLEWARE中的注冊順序,也就是列表的索引值,從前到后依次執行的。
      • 不同中間件之間傳遞的request都是同一個對象
    • 多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執行的,也就是說第一個中間件的process_request方法首先執行,而它的process_response方法最后執行,最后一個中間件的process_request方法最后一個執行,它的process_response方法是最先執行。

    1.2、process_response(self, request, response)

    • 它有兩個參數request和response,request和視圖函數中的request對象一樣,response是視圖函數返回的HttpResponse對象。該方法的返回值也必須是HttpResponse對象。
    • 視圖函數執行之后
    • 注冊順序的倒序

    1.3、process_view(_request_, _view_func_, _view_args_, _view_kwargs_)

    • 該方法有四個參數

      • request是HttpRequest對象。
      • view_func是Django即將使用的視圖函數。 (它是實際的函數對象,而不是函數的名稱作為字符串。)
      • view_args是將傳遞給視圖的位置參數的列表.
      • view_kwargs是將傳遞給視圖的關鍵字參數的字典。 view_args和view_kwargs都不包含第一個視圖參數(request)。
    • Django會在調用視圖函數之前調用process_view方法。

    • 它應該返回None或一個HttpResponse對象。 如果返回None,Django將繼續處理這個請求,執行任何其他中間件的process_view方法,然后在執行相應的視圖。 如果它返回一個HttpResponse對象,Django不會調用適當的視圖函數。 它將執行中間件的process_response方法并將應用到該HttpResponse并返回結果。

    1.4、process_exception(_request_, _exception_)

    • 該方法兩個參數:

      • HttpRequest對象
      • exception是視圖函數異常產生的Exception對象。
    • 這個方法只有在視圖函數中出現異常了才執行,它返回的值可以是一個None也可以是一個HttpResponse對象。如果是HttpResponse對象,Django將調用模板和中間件中的process_response方法,并返回給瀏覽器,否則將默認處理異常。如果返回一個None,則交給下一個中間件的process_exception方法來處理異常。它的執行順序也是按照中間件注冊順序的倒序執行。

    1.5、process_template_response(_request_, _response_)

    • 參數包括HttpRequest對象和response,response是TemplateResponse對象(由視圖函數或者中間件產生)。

    • process_template_response是在視圖函數執行完成后立即執行,但是它有一個前提條件,那就是視圖函數返回的對象有一個render()方法(或者表明該對象是一個TemplateResponse對象或等價方法)。

    2、執行流程

    我們了解了中間件中的5個方法,它們的參數、返回值以及什么時候執行,現在總結一下中間件的執行流程。

    1. 請求到達中間件之后,先按照正序執行每個注冊中間件的process_reques方法,process_request方法返回的值是None,就依次執行,如果返回的值是HttpResponse對象,不再執行后面的process_request方法,而是執行當前對應中間件的process_response方法,將HttpResponse對象返回給瀏覽器。

    2. process_request方法都執行完后,匹配路由,找到要執行的視圖函數,先不執行視圖函數,先執行中間件中的process_view方法,process_view方法返回None,繼續按順序執行,所有process_view方法執行完后執行視圖函數。

    3. process_template_response和process_exception兩個方法的觸發是有條件的,執行順序也是倒序。總結所有的執行流程如下圖所示:

    三、自定義編寫中間件

    1、自定義中間件步驟

    • 創建my_middleware.py文件
    from django.utils.deprecation import MiddlewareMixin
    
    class MD1(MiddlewareMixin):
        def process_request(self, request):
            print("my_middleware_1 里面的 process_request")
    
        def process_response(self, request, response):
            print("my_middleware_1 里面的 process_response")
            return response
    • 注冊中間件
    # 在settings.py中MIDDLEWARE中加入剛創建的my_middleware.py文件
    
    MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'my_middleware.MD1',
    )

    四、中間件版登錄驗證

    需求分析

    • AuthMD中間件注冊后,所有的請求都要走AuthMD的process_request方法
    • 訪問的URL在白名單內或者session中有user用戶名,則不做阻攔走正常流程
    • 如果URL在黑名單中,則返回This is an illegal URL的字符串
    • 正常的URL但是需要登錄后訪問,讓瀏覽器跳轉到登錄頁面
    • 注:AuthMD中間件中需要session,所以AuthMD注冊的位置要在session中間的下方
    # -----------------settings.py-----------------
    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',
      'middlewares.AuthMD',
    ]
    
    # -----------------middleware.py-----------------
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import redirect, HttpResponse
    
    class AuthMD(MiddlewareMixin):
        white_list = ['/login/', ]  # 白名單
        balck_list = ['/black/', ]  # 黑名單
    
        def process_request(self, request):
            next_url = request.path_info
            print(request.path_info, request.get_full_path())
    
            if next_url in self.white_list or request.session.get("user"):
                return
            elif next_url in self.balck_list:
                return HttpResponse('<h2>This is an illegal URL</h2>')
            else:
                return redirect("/login/?next={}".format(next_url))
    
    
    # -----------------urls.py-----------------
    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        url(r'^login/', views.login, name='login'),
        url(r'^index/', views.index, name='index'),
    
    ]
    
    # -----------------views.py-----------------
    from django.shortcuts import render, HttpResponse, redirect
    
    # Create your views here.
    
    def index(request):
        return HttpResponse('<h2>this is index</h2>')
    
    
    def home(request):
        return HttpResponse('<h2>this is home</h2>')
    
    
    def login(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
    
            if user == "yang" and pwd == "123":
                # 設置session
                request.session["user"] = user
                # 獲取跳到登陸頁面之前的URL
                next_url = request.GET.get("next")
                # 如果有,就跳轉回登陸之前的URL
                if next_url:
                    return redirect(next_url)
                # 否則默認跳轉到index頁面
                else:
                    return redirect("/index/")
        return render(request, "login.html")
    
    # -----------------login.html-----------------
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! -->
        <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <title>登錄頁面</title>
    </head>
    <body>
    
    <form action="{% url 'login' %}">
        <p>
            <label for="user">用戶名:</label>
            <input type="text" name="user" id="user">
        </p>
        <p>
            <label for="pwd">密碼:</label>
            <input type="text" name="pwd" id="pwd">
        </p>
        <input type="submit" value="登錄">
    </form>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    </body>
    </html>
    

    五、官方鏈接

    https://docs.djangoproject.com/en/1.11/topics/http/middleware/

    版權聲明:本文為dragonyangang原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/dragonyangang/article/details/79885920

    智能推薦

    django中間件 middleware

    文章目錄 一、中間件 middleware 1.Django框架中的中間件(概念) 2.settings中配置中間件 3.中間件在MVT中的作用機制圖 4.中間件的類和類中方法 ① Request預處理函數 ② View預處理函數 ③ 分界線------------views視圖------------分界線 ④ Template模版渲染函數 ⑤ Exception后處理函數 ⑥ Response...

    Django框架全面講解 -- 中間件(MiddleWare)

    Django框架全面講解 -- 中間件(MiddleWare) django 中的中間件(middleware),在django中,中間件其實就是一個類,在請求到來和結束后,django會根據自己的規則在合適的時機執行中間件中相應的方法。 在django項目的settings模塊中,有一個 MIDDLEWARE_CLASSES 變量,其中每一個元素就是一個中間件,如下圖。   ...

    Django框架(十七)--middleware,自定義管理器

    一、中間件–middleware django中間件是一個輕量級的插件系統,存在于視圖處理前后的請求和響應中。開發人員,可以利用中間件,干預視圖的請求和響應。 中間件是一個面向對象的類,能夠干預視圖的處理,有五種方法。 process_request:在請求后,在process_view之前 process_view:在process_request之后,在執行views之前 執行vi...

    python_fullstack基礎(二)

    python_fullstack基礎(二) 一、變量 1、什么是變量 變量:把程序運行的中間結果臨時存放在內存中,以便后續程序進行調用 2、變量聲明 上述代碼聲明了一個變量,變量名為: name,變量name的值為:”taibai” 3、變量的作用 作用:昵稱,其代指內存里某個地址中保存的內容 4、變量定義規則 變量名只能是 字母、數字或下劃線的任意組合 變量名的第一個字符...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    猜你喜歡

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    精品国产乱码久久久久久蜜桃不卡