在学习 Django 开发时,很多同学会有这样的疑问:
浏览器发起一个请求后,Django 是如何一步步找到对应的视图函数并返回响应的?
本文将带你完整梳理 Django URL 的注册与请求处理流程,让你彻底搞清楚请求从浏览器进入到最终返回结果的全过程。
1. 请求整体处理流程
先看一个 请求执行链路图 (以访问 /hello/ 为例):
python
浏览器 (Client)
│
▼
HTTP 请求 (GET /hello/)
│
▼
WSGI/ASGI Server (Gunicorn / Uvicorn)
│
▼
Django Handler (WSGIHandler / ASGIHandler)
│ 调用 get_response(request)
▼
URL Resolver (基于 ROOT_URLCONF 的 urlpatterns)
│
├─ 匹配 URLPattern: path("hello/", views.hello_view)
▼
视图函数 (views.hello_view)
│ 处理请求,返回 HttpResponse
▼
Django Handler
│ 包装成 response
▼
WSGI/ASGI Server
│
▼
浏览器 (收到响应)
从图中可以看到,主要分为四大阶段:
-
请求进入服务端:浏览器发起请求,经过 WSGI/ASGI 服务器(如 Gunicorn、Uvicorn)。
-
Django 接管请求 :Django 的
WSGIHandler或ASGIHandler处理请求,调用get_response()。 -
URL 匹配 :Django 根据
ROOT_URLCONF中配置的urlpatterns,递归匹配URLPattern或URLResolver。 -
执行视图 :找到对应的视图函数,执行逻辑并返回
HttpResponse,最终由服务器返回给浏览器。
2. URL 的注册方式
在 project/urls.py 中,我们通常会写:
python
from django.urls import path, include
from . import views
urlpatterns = [
path("hello/", views.hello_view), # URLPattern
path("blog/", include("blog.urls")), # URLResolver
]
-
URLPattern
单一的 URL → 对应一个视图函数。例如
path("hello/", views.hello_view)。 -
URLResolver
路由分发器,可以把一部分路由交给子应用。例如
include("blog.urls")。
3. URL 递归匹配机制
Django 的路由匹配是 递归 的:
-
请求
/hello/urlpatterns中直接找到hello/→views.hello_view
-
请求
/blog/list/-
urlpatterns匹配到path("blog/", include("blog.urls")) -
进入
blog/urls.py -
在子路由里找到
path("list/", views.blog_list)
-
这种递归设计让 Django 项目可以方便地 模块化拆分路由。
4. 示例:完整执行过程
假设我们在 views.py 中写了:
python
from django.http import HttpResponse
def hello_view(request):
return HttpResponse("Hello Django!")
再在 urls.py 中注册:
python
urlpatterns = [
path("hello/", hello_view),
]
那么访问 http://127.0.0.1:8000/hello/ 时,执行过程如下:
-
浏览器发起请求
-
Django Handler 接收请求
-
URLResolver 匹配到
hello/ -
调用
hello_view(request) -
返回
HttpResponse("Hello Django!") -
浏览器展示响应内容
5. 总结
本文介绍了 Django URL 注册与请求处理的完整流程,核心要点如下:
-
Django URLConf 由 URLPattern 和 URLResolver 组成
-
URLPattern:路由到单一视图函数
-
URLResolver:通过
include()分发到子应用
-
-
Django URL 匹配是递归的
支持项目模块化,方便维护大型应用。
-
请求执行链路清晰
浏览器请求 → WSGI/ASGI → Django Handler → URLResolver → 视图 → HttpResponse → 浏览器。