You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中404页面为何不执行中间件(Middleware)处理?

问题描述

我在URL配置中设置了如下路径:

path(
    "kitten/",
    views.Kitten.as_view(),
    name="kitten",
),

同时将不存在URL的处理器指向同一个视图:

handler404 = views.Kitten.as_view()

我编写了一个用于设置上下文数据的中间件:

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

    def __call__(self, request):
        return self.get_response(request)

    def process_template_response(self, request, response):
        response.context_data["hasCookie"] = False        
        return response

视图的实现非常简单:

class Kitten(TemplateView):
    template_name = "kitten.html"

模板会输出hasCookie的值。

访问kitten/时能正确显示hasCookie的值,但访问不存在的URL时,虽然加载了正确的模板,却没有显示hasCookie的值。

通过在中间件中添加调试语句发现,访问kitten/时process_view、process_template_response和process_exception都会被调用,但访问不存在的URL时这些方法都未被调用,仅在应用启动时调用了__init__。

为何URL配置中不存在的URL不会触发中间件调用?


原因分析与解决方案

核心原因

Django处理404错误的流程和正常URL匹配流程存在差异:

  • 正常URL匹配成功时,请求会完整经过中间件链路,包括执行__call__方法,以及后续的process_view、process_template_response等钩子函数。
  • 当URL匹配失败触发handler404时,Django是直接调用该处理器视图,并未走中间件的视图处理阶段——仅会执行中间件的__call__方法,但此时还未进入视图的模板响应流程,所以process_template_response这类钩子不会被触发,自然无法给上下文添加hasCookie数据。

解决方案

有两种实用的解决方式:

  1. 修改中间件,在__call__阶段统一处理
    如果需要给所有响应(包括404)添加上下文数据,可以在中间件的__call__方法中,获取响应后判断是否为模板响应,再补充数据:

    class CookieConsentMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
            response = self.get_response(request)
            # 检查是否是带上下文的模板响应
            if hasattr(response, 'context_data'):
                response.context_data["hasCookie"] = False
            return response
    

    这种方式能覆盖正常请求和404请求的所有模板响应场景。

  2. 在视图中手动添加上下文数据
    若仅需给目标视图(含404触发的情况)添加数据,可以重写视图的get_context_data方法:

    class Kitten(TemplateView):
        template_name = "kitten.html"
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context["hasCookie"] = False
            return context
    

    这样不管是正常访问还是404触发,视图都会主动注入上下文数据,无需依赖中间件钩子。

内容的提问来源于stack exchange,提问作者David McKee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:03:12