简而言之,路由系统就是 URL 路径和视图函数的对应关系,也可以称为转发器。
URL 路由系统格式
也就是上一篇提到的 urls.py
这个文件里面的内容就是路由系统的格式。
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('html/', views.myapphtml),
path(route, view, kwargs=None, name=None),
]
主要是调用了 django.urls
的 path()
方法,将多个 path()
方法定义到 urlpatterns
这个列表中。
urlpatterns:一个列表,一个 path()
方法是列表的一个元素,每个元素对应一个视图。
path参数:
- route:表示路径,从端口以后的URL地址。
- view:对应一个函数视图或者类视图(as_view()的结果),必须返回一个 HttpResponse 对象,Django 将这个对象转换成一个 Http 响应。
- kwargs:可选,字典形式数据传递到对应视图中。
- name:可选,URL名称,用作前端代码引用。
URL 路由分发
url 配置解耦,方便管理,也就是各应用多级 URI。比如:http://127.0.0.1:8000/myapp/blog/
示例:之前创建了一个 myapp 的应用,作为一个模块存在,访问路径为 http://127.0.0.1:8000/html/
,现在把这个访问路径改为 http://127.0.0.1:8000/myapp/blog/
以下是作为应用 myapp 的 urls.py 文件的编写
# devops/myapp/urls.py
from django.urls import path
from myapp import views
urlpatterns = [
path('blog/', views.myapphtml),
]
devops 项目的 urls.py
from django.contrib import admin
from django.urls import path, include # 新增 include
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('myapp/', include('myapp.urls')), # 将应用的urls.py引入
]
启动项目后即可访问:http://127.0.0.1:8000/myapp/blog/
可以尝试练习多个应用,不同页面的做 URL 路由分发。路由分发就是为了让看到 URL 的时候可以清晰的看到对应的模块功能,排错也会好找。
URL 正则匹配
URL 路径也可以使用正则表达式匹配,使用 re.path()
代替 path()
。
比如博客的一些归档 URL 是带有日期的。如:https://www.feiyiblog.com/2020/10/16/Kubernetes%E4%BD%BF%E7%94%A8kube-ovn%E7%BD%91%E7%BB%9C%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4/
# devops/urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
re_path('myapp/([0-9]{4})/([0-9]{2})', views.year_mouth),
]
# devops/myapp/views.py
## 新增
# 由于 urls.py 中使用了myapp/([0-9]{4})/([0-9]{2})正则分组,所以这可以作为位置变量传参使用的
def year_mouth(request, year, mouth):
return HttpResponse("这是%s年%s月文章列表" % (year, mouth))
运行项目后访问 http://127.0.0.1:8000/myapp/2023/12/
。这里的年月可自己定义,因为已经通过正则作为变量传到代码里了,所以没有局限。
使用正则分组还有一个功能,给分组命名,通过命名,在视图中引用分组名,可以不用局限于位置参数。
# devops/urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
re_path('myapp/(?P<year>[0-9]{4})/(?P<mouth>[0-9]{2})', views.year_mouth), # 分组命名为year和mouth
]
# devops/myapp/views.py
def year_mouth(request, mouth, year): # 这里传参的位置不需要固定,需要注意的是,这里传参的名字需要和正则分组名一致
return HttpResponse("这是%s年%s月文章列表" % (year, mouth))
URL 名称
这个功能主要是在 html 中使用超链接的时候方便引用地址
# devops/urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index, name='index'), # 这里的name就是给这个index/命名的,意思是无论 index/ 怎么改变,html中只要引用这个name就可以
re_path('myapp/([0-9]{4})/([0-9]{2})', views.year_mouth),
]
# template下某html
<a href="{ % url 'index' %}">你好,index</a> # 超链接href引用index