URL 路由
path、命名 URL 与 reverse。
URL 路由
这一课你将能做到
- 用
path()写出带类型转换器、可选参数和正则匹配的路由 - 用
name给路由命名,并在视图/模板中通过reverse()和{% url %}反查 URL - 用
include()把 URL 按 app 拆分,让项目根路由保持干净
为什么要学
URL 路由是 Web 框架的「门面」。用户输入什么地址,服务器执行什么代码,全由路由决定。Django 的路由系统虽然不像 Flask/FastAPI 那样用装饰器直接注册,但借助 urls.py 的显式声明,反而在大项目里更容易定位、排查和做 URL 全局替换。
对比 Spring Boot:Spring 用 @GetMapping("/users/{id}") 注解在控制器上声明;Django 把路由抽成独立的 urls.py,控制器(View)只写业务逻辑。两种思路:Java 是「控制器在哪里,路由就在哪里」;Django 是「路由集中管理,视图只管响应」。
先建立图像
请求 GET /articles/2024/python-orm/
│
▼
urls.py 逐条匹配
path("articles/<int:year>/<slug:slug>/", views.article_detail)
│
▼
views.article_detail(request, year=2024, slug="python-orm")
跟着做
步骤 1:基础 path 与转换器
blog/urls.py:
from django.urls import path
from . import views
app_name = "blog"
urlpatterns = [
path("", views.index, name="index"),
path("<int:year>/", views.year_archive, name="year_archive"),
path("<int:year>/<int:month>/", views.month_archive, name="month_archive"),
path("<int:year>/<int:month>/<slug:slug>/", views.article_detail, name="detail"),
]
blog/views.py:
from django.http import HttpResponse
def index(request):
return HttpResponse("首页")
def year_archive(request, year):
return HttpResponse(f"{year} 年归档")
def month_archive(request, year, month):
return HttpResponse(f"{year} 年 {month} 月归档")
def article_detail(request, year, month, slug):
return HttpResponse(f"文章:{year}/{month}/{slug}")
int 和 slug 是 Django 自带的 path converter:int 匹配正整数;slug 匹配 ASCII 字母/数字/连字符/下划线,常用于 URL 友好的文章标题缩写。
步骤 2:自定义转换器
如果内置转换器不够用,你可以自己写。例如:匹配 4 位年份:
# blog/converters.py
class FourDigitYearConverter:
regex = r"[0-9]{4}"
def to_python(self, value):
return int(value)
def to_url(self, value):
return f"{value:04d}"
注册: