python - process_request出错时django中间件的执行顺序是怎样的?

标签 python django django-middleware chain-of-responsibility request-response

我正在研究 Django 中间件代码库。我查看了下图 enter image description here

所以,这张图已经很清楚了。

但是我有一些问题

  1. 当 process_request() 中间件出现异常时会发生什么?它是如何处理的?会调用 response_middleware 吗?例如。如果AuthenticationMiddlewareprocess_view()出现异常,那么是否会调用MessageMiddlewareprocess_response()

  2. 当 process_response() 中间件返回响应时会发生什么?例如。如果 AuthenticationMiddlewareprocess_view() 返回响应,那么 MessageMiddlewareprocess_response() 会被调用吗?或者它将从 AuthenticationMiddleware 返回(即,它将调用 AuthenticationMiddlewareprocess_response(),但不会调用 process_response MessageMiddleware的())

我已经调试了 1.10 中使用新样式中间件类的 django 的行为,但我不熟悉旧的 MIDDLEWARE_CLASSES 设置?

对于 django 1.10:- 1) 如果 AuthenticationMiddlewareprocess_request() 返回响应,则 process_template_response()process_response() 将被调用如下图所示的所有中间件。

2) 如果 AuthenticationMiddlewareprocess_request() 引发异常,则行为也相同。

纠正我,如果我错了。

提前致谢。

最佳答案

The official documentation如果你在 1.10 版本之前的 django 项目上工作,可以回答你的第一个问题。

请阅读段落:使用 MIDDLEWARE 和 MIDDLEWARE_CLASSES 之间的行为差​​异

Under MIDDLEWARE_CLASSES, every middleware will always have its process_response method called, even if an earlier middleware short-circuited by returning a response from its process_request method. Under MIDDLEWARE, middleware behaves more like an onion: the layers that a response goes through on the way out are the same layers that saw the request on the way in. If a middleware short-circuits, only that middleware and the ones before it in MIDDLEWARE will see the response.

然而 MIDDLEWARE_CLASSES 自 django v1.10 以来已被删除,并且从那时起引入了新样式的中间件工作流(使用 __call__() 代替),这允许每个中间件(应用在MIDDLEWARE)内部判断是否短路,通过返回response(有错误状态),不调用后续的中间件,查看中间件的异常处理,这种情况下图问题可能并非总是如此,尤其是当您的项目包含自定义中间件时。

[旁注],异常短路的中间件可能如下所示:

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

    def __call__(self, request):
        try:
            # Code to be executed for each request before
            # the view (and later middleware) are called.
            do_something_but_raise_exception()
            response = self.get_response(request)
            # Code to be executed for each request/response after
            # the view is called.
        except WHATEVER_EXCEPTION as e:
            # short-circuiting, because self.get_response() is not invoked,
            response = generate_custom_response(e)
        return response

[旁注]:

值得一提的是,FastAPI 中的中间件也以类似的方式构建。

关于python - process_request出错时django中间件的执行顺序是怎样的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49365722/

相关文章:

python - 如何在外部函数中重新绑定(bind)名称?

python - Pandas 获取两个索引之间的交集位置

Django Guardian - 如何在基于类的 View 中使用 permission_required 装饰器?

python - Django 在 PermissionDenied 异常引发时打印错误

python - Django 错误 : ImproperlyConfigured: WSGI application

python - 如何比较来自两个不同字典的相同键值与百分比

python - 执行笛卡尔积时如何减少内存消耗?

django 测试 - 如何获取响应数据以备将来使用

python - 修改django admin中删除对象时的警告信息?

Django 在每个 View 中显示消息