[ django[middleware]中间件源码解析 ]


源码执行顺序

1. 通过嵌套装饰器wraps实现, 调用__call__魔术方法, 先执行request [321]里到外, 再执行response [123]外到里

from functools import wraps

def ex(get_response):
    @wraps(get_response)
    def inner(request):
        try:
            print('wraps-request')
            response = get_response(request)
        except Exception as exc:
            response = 'error'
        return response
    return inner


class Min:
    def __init__(self, get_response, *args, **kwds):
        print('init', self, *args, **kwds)
        self.get_response = get_response

    def __call__(self, request, *args, **kwds):
        print('call', self, args, kwds)
        if hasattr(self, 'request'):
            response = self.request(request)
        response = response or self.get_response(request)
        if hasattr(self, 'response'):
            response = self.response(request)
        return response


class M1(Min):
    def request(self, request):
        print(f'M1: request:{request}')

    def response(self, request):
        print(f'M1: response:{request}')


class M2(Min):
    def request(self, request):
        print(f'M2: request:{request}')

    def response(self, request):
        print(f'M2: response:{request}')


class M3(Min):
    def request(self, request):
        print(f'M3: request:{request}')

    def response(self, request):
        print(f'M3: response:{request}')

def get_response(request):
    print(f'最终的response: {request}')


get_response_1 = ex(get_response)   # 基础层 , 保存函数
m1 = M1(get_response_1)
# 第二层 , 保存m1 self.get_response = self.get_response1
get_response_2 = ex(m1)
m2 = M2(get_response_2)
# 第三层 , 保存m2 self.get_response = self.get_response2
get_response_3 = ex(m2)
m3 = M3(get_response_3)
print(m3(request='request_main'))


'''
执行顺序
request:    3,2,1  没有返回
执行自己的视图内容
response:   1,2,3 有返回
'''