Skip to content

twtrubiks/django_middleware_tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

django-middleware-tutorial

這篇文章主要是要和大家簡單介紹 django 中的 middleware 是什麼:notebook:

本篇 django 版本使用 Django==4.2.6, 如果不知道什麼是 Django, 建議可以閱讀

Django 基本教學 - 從無到有 Django-Beginners-Guide, 教你建立自己的第一個 Django 程式

簡介

django middleware 官方文件

Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.

簡單說, middleware 的存在就是為了可以更簡單的全局管理(加工) django 的 輸入/輸出, 有點類似裝飾器的概念.

( 如果不知道什麼是裝飾器, 請參考 What is the python decorator )

在 django 中, 你說你從來沒使用過 middleware, 其實是有的, 只是你不知道你有使用過而已:sweat_smile:

settings.py 中的 MIDDLEWARE, 就有非常多已經實做好的 middleware:smirk:

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',
]

教學

首先, 先建立 middleware/middleware.py, 以下為片段 code,

...

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

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

        logger.warning('---- 1 ----')
        response = self.get_response(request)
        logger.warning('---- 4 ----')

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

        return response


    # process_view(), process_exception(), process_template_response()
    # special methods to class-based middleware

    def process_view(self, request, view_func, view_args, view_kwargs):
        # process_view() is called just before Django calls the view.
        # It should return either None or an HttpResponse object
        logger.warning('---- 2 ----')
        return None

    def process_exception(self, request, exception):
        # Django calls process_exception() when a view raises an exception
        # It should return either None or an HttpResponse object
        logger.warning('---- exception.args ----')
        return None

    def process_template_response(self, request, response):
        # return TemplateResponse object
        logger.warning('---- 3 ----')
        return response

__init__ 只會執行一次, 就是 django 啟動的時候會載入.

__call__ 所謂的 callable.

( 如果不知道什麼是 callable, 請參考 __call__tutorial.py ) youtube - What is the __call__ in python

response = self.get_response(request) 前後代表每個 request 開始與結束會執行的地方.

其中, 裡面的 process_view() process_exception() process_template_response(),

這三個是屬於比較特別的方法,

process_view()

process_view() is called just before Django calls the view.

It should return either None or an HttpResponse object.

process_exception()

Django calls process_exception() when a view raises an exception.

It should return either None or an HttpResponse object.

process_template_response()

process_template_response() is called just after the view has finished executing,

if the response instance has a render() method, indicating that it is a TemplateResponse

or equivalent.

activating middleware, 記得要將 middleware 加入 settings.py 中, 這樣才會生效:+1:

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',
    'middleware.middleware.SimpleMiddleware', # <------- activating middleware
]

直接執行 python manage.py runserver,

瀏覽 http://127.0.0.1:8000/musics/ 觀察 logging.

另外要注意的點是, django 保留了 class django.utils.deprecation.MiddlewareMixin

Django provides django.utils.deprecation.MiddlewareMixin to ease creating middleware classes that are compatible with both MIDDLEWARE and the old MIDDLEWARE_CLASSES. All middleware classes included with Django are compatible with both settings.

以下為官網原文片段,

If used with MIDDLEWARE_CLASSES, the __call__() method will never be used; Django calls process_request() and process_response() directly.

所以說如果你使用了以前的 MIDDLEWARE_CLASSES, __call__() method 將會失效.

可參考 Upgrading pre-Django 1.10-style middleware

Donation

文章都是我自己研究內化後原創,如果有幫助到您,也想鼓勵我的話,歡迎請我喝一杯咖啡:laughing:

綠界科技ECPAY ( 不需註冊會員 )

alt tag

贊助者付款

歐付寶 ( 需註冊會員 )

alt tag

贊助者付款

贊助名單

贊助名單

License

MIT license

About

介紹 django 中的 middleware

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages