class LoggingMiddleware(object): def process_request(self, request): request.start_time = time.time() def process_response(self, request, response): execute_time = time.time() - request.start_time path = request.get_full_path() info_logger.info('request %s execute_time %f' % (path, execute_time)) return response
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'mobile.middlewares.LoggingMiddleware', )
1 中间件可以保证 process_request 和 process_response 方法不会多线程并发, 所以 2 个方法中的 request 肯定是同一个 request
2 方法中不要引用全局变量或当前类中的变量,否则在多线程并发或协程中会有问题
3 process_request 按顺序从上往下执行, process_response 会反过来从下往上执行
4 如果你的 urlconf 中末尾带反斜线 / , 当链接中不带反斜线时,CommonMiddleware 会把请求重定向到带反斜线的 url
5 这里有一个坑, 当 CommonMiddleware 中请求被从定向时, 后面所有中间件的 process_request 都不会被执行, 但所有中间件的 process_response 还是会反过来执行,
这种情况下上面的 LoggingMiddleware process_response 方法 就会报异常,因为没有 request.start_time
6 解决方法,把两个中间件换一下位置, 但这样会多记录一个不带反斜线的请求(不带反斜线的请求不存在), 还有就是把链接中所有请求都加上反斜线,但由于历史原因
可能有时也加不全。