路由层 URLConf
路由的作用,是决定“一个请求该交给哪个视图处理”。
浏览器访问网站时,请求到达的只是一个 URL,例如:
//login//article/12/
Django 必须知道:这些地址分别该交给哪段 Python 代码去处理。这件事就是路由在做。
本节目标
- 理解路由层的作用
- 学会使用
path()配置基础路由 - 学会接收 URL 参数
- 理解路径转换器
- 理解
include()做分层路由 - 理解重定向和命名路由的基础概念
为什么需要路由
如果没有路由,Django 就不知道:
/users/应该执行哪个视图/articles/应该执行哪个视图/login/应该执行哪个视图
所以路由本质上是一套“地址分发规则”。
一个最基础的路由示例
项目 urls.py:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path("admin/", admin.site.urls),
path("hello/", views.hello),
]视图:
from django.http import HttpResponse
def hello(request):
return HttpResponse("你好,Django")访问:
http://127.0.0.1:8000/hello/页面显示:
你好,Django这就是一个最基础的 URL 到视图的绑定过程。
path() 是什么意思
最常见的路由写法就是:
path("hello/", views.hello)它的含义是:
- 当访问
hello/ - 就调用
views.hello
所以你可以先把 path() 理解成:
- 一条地址匹配规则
urlpatterns 是什么
urlpatterns = [
...
]它是 Django 路由规则的列表。
你可以把它理解成:
- 整个项目的“地址规则清单”
根路径和普通路径
首页
path("", views.home)这里的空字符串表示网站根路径,也就是:
/普通路径
path("about/", views.about)对应:
/about/URL 参数
很多页面不是固定路径,而是带参数的。
例如文章详情页:
/article/12/这里的 12 通常就是文章编号。
路由写法:
path("article/<int:article_id>/", views.article_detail)视图写法:
from django.http import HttpResponse
def article_detail(request, article_id):
return HttpResponse(f"文章编号是:{article_id}")访问:
/article/12/页面显示:
文章编号是:12这说明 URL 中的参数已经被 Django 自动传给视图了。
路径转换器
路由参数里常见的转换器有:
strintsluguuid
str
默认字符串。
int
只能匹配整数。
slug
常用于文章别名、短字符串标识。
uuid
常用于 UUID 类型标识。
路径转换器的作用,是让 URL 参数更有约束。
为什么路径转换器重要
例如:
path("article/<int:article_id>/", ...)就表示:
- 这里只接受整数
如果访问:
/article/abc/它不会匹配成功。
这能帮助你减少无效请求和异常情况。
路由分层:include()
项目一大之后,不可能把所有路由都堆在一个 urls.py 里。
这时候通常会按 app 拆分。
项目主路由:
from django.urls import path, include
urlpatterns = [
path("users/", include("users.urls")),
]然后 users/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("login/", views.login_view),
path("register/", views.register_view),
]这样最终访问路径会变成:
/users/login//users/register/
为什么要拆路由
因为大项目的地址会越来越多。
拆分之后的好处是:
- 结构更清晰
- 各 app 边界更明确
- 更容易维护
命名路由
除了直接写路径,Django 还支持给路由起名字。
path("login/", views.login_view, name="login")这表示:
- 这条路由的名字叫
login
好处是:
- 后面模板和代码中可以通过名字引用路由
- 不必到处手写固定路径字符串
零基础阶段先知道这个概念即可。
重定向
有时候视图并不是直接返回页面,而是跳转到另一个地址。
from django.shortcuts import redirect
def old_page(request):
return redirect("/new-page/")这表示访问旧地址时,自动跳到新地址。
静态资源和业务路由的区别
你后面会接触这些资源:
- 图片
- CSS
- JavaScript
这些和普通业务页面路由不是一回事。
例如:
/login/是业务页面路由/static/style.css是静态资源访问路径
零基础阶段你先知道这是两类不同东西即可。
一个完整小案例
主路由:
from django.urls import path
from . import views
urlpatterns = [
path("", views.home),
path("course/", views.course_list),
path("course/<int:course_id>/", views.course_detail),
]视图:
from django.http import HttpResponse
def home(request):
return HttpResponse("首页")
def course_list(request):
return HttpResponse("课程列表页")
def course_detail(request, course_id):
return HttpResponse(f"课程编号:{course_id}")访问结果:
/-> 首页/course/-> 课程列表页/course/3/-> 课程编号:3
这个例子已经把:
- 普通路由
- 根路径
- 带参数路由
串起来了。
常见错误
1. 路由写了,但视图没导入
这会直接报错。
2. 访问地址和路由规则不一致
例如路由写的是:
path("hello/", ...)却访问成别的路径,就不会匹配成功。
3. 参数写了,但视图函数没接收
如果路由里写了:
<int:article_id>视图函数也必须接对应参数。
4. 所有路由都堆在一个文件里
项目一大之后会很难维护。
练习题
练习 1
写一个路由,让访问 /hello/ 时返回一句欢迎语。
练习 2
写一个首页路由 /。
练习 3
写一个详情页路由 /article/<int:id>/,并把 id 显示出来。
练习 4
尝试给一个路由加 name 参数。
练习 5
自己解释:
- 路由到底解决什么问题
- 为什么项目大了要用
include()拆分路由
本节小结
路由层的本质,就是把不同 URL 请求分发给正确的视图处理。
你最重要的收获应该是:
- 会写最基础的
path() - 知道根路径和普通路径怎么配
- 会接收 URL 参数
- 理解路径转换器
- 知道大项目中路由为什么要拆分
只要这一层理解清楚,后面 Django 的页面、详情页、接口和模块结构就都能顺着搭起来。