一、路由转发
通常,我们会在每个app里,各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到相应的urls.py模块中。
路由转发使用的是include()方法,需要提前导入,其参数是转发目的地路径的字符串,路径以圆点分割。
每当Django遇到include()时,它会去掉URL中匹配的部分并将剩下的字符串发送给include的URLconf做进一步处理,也就是转发到二级路由取。
另外一种转发其他URL模式的方式是使用一个path()实例的列表。
两种转发方式,如下图:
但是第二种做法,相当于把二级路由模块内的代码写到根路由模块里一起了,所以不是很推荐。
二、捕获参数
目的地URLconf会收到来自父URLconf捕获的所有参数,如下面的例子:
# In settings/urls/main.py from django.urls import include, path urlpatterns = [ path('<username>/blog/', include('foo.urls.blog')), ] # In foo/urls/blog.py from django.urls import path from . import views urlpatterns = [ path('', views.blog.index), path('archive/', views.blog.archive), ]
在上面的例子中,捕获的“username”变量将会被传递给include()指向的URLconf,再进一步传递给对应的视图。
三、向视图传递额外的参数
URLconf具有一个钩子,允许你传递一个python字典作为额外的关键字参数给视图函数,像下面这样:
from django.urls import path from . import views urlpatterns = [ path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}), ]
在上面的例子中,对于/blog/2005/请求,Django将调用views.year_archive(request,year,foo)。理论上,你可以在这个字典里传递任何你想要传递的东西。但是要注意,URL模式捕获的命名关键字参数和在字典中传递的额外参数有可能具有相同的名称,这会发生冲突,要避免。
四、传递额外的参数给include()
类似上面,也可以传递额外的参数给include()。参数会传递给include指向的URLconf中的每一行。
注意,只有当你确定被include的URLconf中的每个视图都接收你传递给它们的额外的参数时才有意义,否则其中一个以上视图不接收该参数都将导致错误异常。