9

我正在研究 django 中间件代码库。我查看了下图在此处输入图像描述

所以,图很清楚。

但我有一些问题

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

  2. 在 process_response() 中间件返回响应时会发生什么?例如。如果process_view()ofAuthenticationMiddleware返回响应,那么会调用process_response()of吗?MessageMiddleware或者它会从AuthenticationMiddleware(即,它会调用process_response()of AuthenticationMiddleware,但不会调用process_response()of MessageMiddleware)返回

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

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

2)如果process_request()forAuthenticationMiddleware引发异常,那么行为也将相同。

纠正我,如果我错了。

提前致谢。

4

2 回答 2

1

如果您在 1.10 版本之前从事 django 项目,官方文档可以回答您的第一个问题。

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

在 MIDDLEWARE_CLASSES 下,每个中间件都将始终调用其 process_response 方法,即使较早的中间件因从其 process_request 方法返回响应而短路。在 MIDDLEWARE 下,中间件的行为更像一个洋葱:响应在输出时经过的层与在输入时看到请求的层相同。如果中间件短路,则只有该中间件和它之前的中间件进入MIDDLEWARE 将看到响应。

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

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

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 中的中间件也以类似的方式构建。

于 2020-11-25T06:49:26.890 回答
0

对于 2),你是对的。函数convert_exception_to_response()将捕获process_request()引发的异常。
查看源代码:
https ://github.com/django/django/blob/master/django/core/handlers/base.py https://github.com/django/django/blob/master/django/core/handlers /异常.py

于 2019-03-07T09:27:00.847 回答