【Django】Django的上下文處理器(Context Processor)和中間件(Middleware)(十一)


這一篇教程,我們一起來了解Django的上下文處理器(Context Processor)和中間件(Middleware)。

對於這兩塊內容,我們最好先了解概念和原理,才能比較好的去應用它們。

一、上下文處理器(Context Processor)

上下文處理器也稱作上下文渲染器。

我個人認爲處理比渲染更容易理解,而且英文中“Processor”的意思是處理,“Render”的意思是渲染。

但是稱爲上下文渲染器也有道理,渲染更接近於使用場景。

Django中的Context Processor主要是應用於模板,完成頁面的繪製的一些處理,也就是所說的頁面渲染。

還有,上下文又是什麼?

這個概念,感覺很難懂。

從語文的角度來說,上下文是語境;

同一句話,在不同的語境中,會有不同的意思。

例如,小明考試成績100分,爸爸說“幹得漂亮”,這是表揚的意思。

而小明考試成績0分,爸爸說“幹得漂亮”,這是諷刺的意思。

所以,同樣的一句話,我們需要和上文聯繫到一起才能明白真正的意思。

從計算機編程角度來說,上下文是環境。

也就是說,同一段處理程序對於不同的環境,反饋出不同的處理結果。

借用網上的一個例子:用戶訪問站點的時候,站點的所有頁面上都要能夠顯示這個用戶自己的IP地址。

這樣的功能,我們需要從請求(request)中獲取到訪問用戶的IP地址,然後呈現到頁面中。

也許大家能夠想到,我們可以在每個頁面對應的視圖函數中進行這個處理,但是未免太過麻煩。

最好的方式是將處理過程定義一次,就能夠在每個頁面中使用。

此時,我們可以通過自定義一個上下文處理器幫助我們完成。

面對不同來源的用戶通過同一個處理器完成頁面上不同IP地址的渲染。

1、創建上下文處理器

在項目文件夾(“wsgi.py”所在的文件夾)新建一個文件“context_processor.py”。

在這個文件中添加獲取用戶IP地址的代碼。

示例代碼:

def getuserip(request):
    ip = request.META['REMOTE_ADDR']
    if ip == '127.0.0.1':
        return {'user_type': '本機用戶'}
    return {'user_type': '外部用戶(%s)' % ip}

注意:上下文處理器必須返回一個字典。

2、將上下文處理器添加到模板設置

打開文件“settings.py”,在模板設置中添加處理器中的函數。

TEMPLATES = [
    {
        ...省略部分代碼...
        'OPTIONS': {
            'context_processors': [
                ...省略部分代碼...
                'MyProject.context_processor.getuserip'
            ],
        },
    },
]

上方代碼中,紅色部分爲新增代碼。

3、在頁面模板中添加標記

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
當前訪問用戶:{{ user_type }}
</body>
</html>

完成上述代碼後,Django調用模板時會先通過上下文處理器進行處理,並將處理後返回的數據字典傳入模板,通過模板標記獲取數據。

此時,我們就可以打開開發服務器,進行訪問測試了。

注意:如果需要允許外部訪問,需要監聽所有IP地址,服務器啓動命令爲:runserver 0.0.0.0:端口號,也可以簡寫爲runserver 0:端口號

本機訪問結果:

外部訪問結果:(例如手機)

二、中間件(Middleware)

中間件,我們需要搞清楚它在什麼中間,起到什麼作用?

根據官方文檔的說法,中間件是請求(request)與響應(response)之間的鉤子(hooks)框架。

…又多了個鉤子。

個人理解鉤子實際上就是掛在主程序上的監控程序,當主程序運行中滿足了鉤子的觸發條件時,執行鉤子的處理程序。

在官方文檔中,給出的中間件示例非常簡單直觀,並且包含了兩種寫法。

1、以函數的形式定義中間件。

示例代碼:

def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware

2、以類的形式定義中間件

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

那麼,中間件怎麼使用?能起到什麼樣的作用呢?

依然通過舉例說明。

例如,我們發佈的項目只允許本機和指定ip訪問,不允許外部其他地址的設備訪問,就可以通過中間件來實現。

首先,創建一箇中間件文件“middleware.py”,並定義訪問限制的中間件。

這個文件可以創建一個新的Package進行存放,例如:MW。

示例代碼:

from django.http import HttpResponseForbidden

class AaccessRestrictionMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response
        self.wite_ip = ['127.0.0.1', '192.168.31.18']  # 初始化ip地址白名單

    def __call__(self, request):
        ip = request.META['REMOTE_ADDR']  # 獲取訪問用戶的ip
        if ip not in self.wite_ip:  # 如果ip不在白名單中
            return HttpResponseForbidden('您被禁止訪問!')  # 返回響應
        response = self.get_response(request)
        return response

然後,我們打開文件“settings.py”,在中間件設置中添加中間件的類。

示例代碼:

MIDDLEWARE = [
    'MW.middleware.AaccessRestrictionMiddleware',
    ...省略其他中間件...
]

通過以上操作,我們就可以限制只有IP白名單中的用戶才能夠訪問我們的項目。

中間件比較像遊戲的外掛程序,遊戲主程序的執行過程中一旦滿足觸發外掛的情形出現,外掛就會執行相應的處理。但是,外掛並不會改變主程序,當我們不需要外掛的時候,只需要移除外掛程序,主程序依然能夠正常的執行。

本節練習源代碼:【點此下載

轉載請註明:魔力Python » Django2:Web項目開發入門筆記(24)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章