如何在django中间件中记录请求id?

问题描述 投票:0回答:1

我写了一些代码如下,但它引发了异常

这里是request_id_middleware.py

import uuid

from django.middleware.common import CommonMiddleware
from taiji.logger import logger

class RequestIDMiddleware(CommonMiddleware):
    # pass
    def process_request(self, request):
        request.META['request_id'] = str(uuid.uuid4())
        logger.info(f"start request id: {request.META['request_id']}")
        return request

    def process_response(self, request, response):
        if request.META.get('request_id') is None:
            response.headers['X-REQUEST-ID'] = request.META['request_id']
            logger.info(f"finish request id: {response.headers['X-REQUEST-ID']}")
        return response

记录器.py

import logging


def set_logger(name):
    logger=logging.getLogger(name)
    handler=logging.StreamHandler()
    handler.setLevel(logging.DEBUG)
    fmt=logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(fmt)
    logger.addHandler(handler)
    return logger

logger=set_logger('gg')

观点

def index(request: HttpRequest):
    logger.info("hello world")
    return JsonResponse("hello world")

但它告诉我

Traceback (most recent call last):
  File "E:\miniconda\envs\py312\Lib\wsgiref\handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\miniconda\envs\py312\Lib\site-packages\django\contrib\staticfiles\handlers.py", line 80, in __call__
    return self.application(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\miniconda\envs\py312\Lib\site-packages\django\core\handlers\wsgi.py", line 124, in __call__
    response = self.get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\miniconda\envs\py312\Lib\site-packages\django\core\handlers\base.py", line 141, in get_response
    response._resource_closers.append(request.close)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'WSGIRequest' object has no attribute '_resource_closers'
[20/Apr/2024 22:32:59] "GET /index/ HTTP/1.1" 500 59

这是实现中间件的正确方法吗? 为什么它会调用 WSGIRequest 错误?它应该是一个类似响应的对象错误 任何帮助将不胜感激

python django
1个回答
0
投票

问题似乎出在中间件中的

process_response
方法。您正在尝试访问
response.headers
,但 Django 的响应对象没有
headers
属性。相反,您应该直接在响应对象上设置标头。尝试像这样更新你的中间件:

import uuid
from django.http import JsonResponse

class RequestIDMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.META['request_id'] = str(uuid.uuid4())
        response = self.get_response(request)
        response['X-REQUEST-ID'] = request.META['request_id']
        return response

修改后,中间件应在每个响应上设置

X-REQUEST-ID
标头。只需确保在 Django 项目的
MIDDLEWARE
设置中相应地更新您的中间件注册即可。

© www.soinside.com 2019 - 2024. All rights reserved.