文章

Django 处理 404 的逻辑流程

Django 处理 404 的完整逻辑流程(结合自定义 NotfoundViewhandler404 配置):

1. 用户访问 URL

  • 用户在浏览器输入一个 URL,比如:
    https://quillnk.com/abc/xyz
  • Nginx 收到请求,转发到 uWSGI → Django

2. Django URL 路由匹配

  • Django 根据 urls.py 中的路由表,逐条尝试匹配。

  • 如果没有任何路由匹配,就会触发 404 错误

3. Django 调用 handler404

  • 默认情况下,Django 会调用内置的 django.views.defaults.page_not_found,返回一个简单的 404 Not Found 页面。

  • 但在 urls.py 里配置了:

    handler404 = NotfoundView.as_error_view()
  • 所以 Django 会调用你自定义的 NotfoundView

4. 执行 NotfoundView.aserrorview() 包装函数

  • as_error_view() 会把类视图 NotfoundView 转换成一个函数,符合 Django 要求的 (request, exception) 签名。

  • Django 会调用这个函数,并传入:

    • request:当前请求对象

    • exception:触发 404 的异常对象(通常用不到)

5. 渲染自定义 404 页面

  • NotfoundView 继承自 TemplateView,最终调用 get_context_data() 构造模板上下文:

    • breadcrumbs(PC 端面包屑)

    • breadcrumbs_mobile(移动端面包屑)

  • 使用 template_name = 'blog/404.html' 渲染页面。

6. 确保返回 404 状态码

  • wrapped_view 内部:
if not isinstance(response, HttpResponseNotFound):     
	response.status_code = 404
  • 确保返回的 HttpResponse 状态码是 404

7. 浏览器最终收到响应

  • 用户看到的是 你自定义的 404 页面,而不是默认的 "Not Found"

  • 响应头中的状态码是 404,搜索引擎和前端应用可以正确识别。

完整流程总结

  1. 请求进来 → Nginx → uWSGI → Django

  2. Django 路由表无匹配 → 触发 404

  3. Django 调用 handler404 → 进入 NotfoundView.as_error_view()

  4. NotfoundView 渲染 blog/404.html 模板

  5. 返回 HttpResponse,状态码设为 404

  6. 浏览器显示自定义 404 页面

本文由作者按照 CC BY 4.0 进行授权。