在 Django 中,URL 配置是项目的入口。我们经常会在 urls.py
中看到 path()
和 include()
,但很多初学者会搞混:
-
URLPattern 和 URLResolver 有什么区别?
-
它们在 Django 的请求处理流程中扮演什么角色?
本文将详细拆解这两个核心对象,并配合实例帮助你彻底理解。
1. URLConf 是什么?
在 Django 项目中,ROOT_URLCONF
配置项指定了全局 URL 配置文件,一般是 project/urls.py
。
示例:
python
# project/urls.py
from django.urls import path, include
from . import views
urlpatterns = [
path("hello/", views.hello_view), # URLPattern
path("blog/", include("blog.urls")), # URLResolver
]
-
urlpatterns
是一个 列表 -
列表中可以包含 URLPattern 或 URLResolver
-
Django 会递归匹配,直到找到最终的视图函数
2. URLPattern 是什么?
URLPattern 代表一个单一的路由规则,通常使用 path()
或 re_path()
定义。
例如:
python
path("hello/", views.hello_view)
-
URL :
hello/
-
视图函数 :
views.hello_view
-
作用 :当请求路径匹配
hello/
时,直接调用hello_view
视图函数。
换句话说,URLPattern 就是一条最小的 URL 映射规则。
3. URLResolver 是什么?
URLResolver 用于路由分发,通常通过 include()
引入子路由。
示例:
python
# project/urls.py
path("blog/", include("blog.urls"))
在 blog/urls.py
中继续定义:
python
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("list/", views.blog_list),
path("detail/<int:id>/", views.blog_detail),
]
请求 /blog/list/
时的执行过程:
-
Django 在
project/urls.py
中找到匹配项path("blog/", include("blog.urls"))
-
进入
blog/urls.py
-
匹配到
path("list/", views.blog_list)
-
执行视图函数
blog_list
这样就实现了 递归匹配。
4. URLPattern vs URLResolver 对比图
python
project/urls.py (ROOT_URLCONF)
│
├─ URLPattern: "hello/" → views.hello_view
│
└─ URLResolver: "blog/" → include("blog.urls")
│
├─ URLPattern: "list/" → views.blog_list
└─ URLPattern: "detail/<int:id>/" → views.blog_detail
-
URLPattern
-
一对一映射
-
匹配后直接执行视图函数
-
-
URLResolver
-
递归分发
-
匹配后进入子路由继续查找
-
5. 为什么要区分?
如果没有 URLResolver,那么所有路由规则都必须写在 project/urls.py
,会导致文件非常庞大,不利于维护。
通过 URLResolver:
-
可以把不同模块的路由拆分到子应用
-
项目更清晰、可扩展性更强
-
也更符合 Django 的 app 解耦思想
6. 总结
-
URLPattern:最小的路由匹配单元,直接指向视图函数。
-
URLResolver:路由分发器,用于包含子路由,实现递归匹配。
-
Django 的路由匹配是递归的,直到找到一个具体的 URLPattern。