Django URL调度器
Django处理请求的流程
- Django确定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但如果传入 HttpRequest对象具有urlconf 属性(由中间件设置),则将使用其值代替 ROOT_URLCONF设置。
- Django加载Python模块并查找变量urlpatterns。这应该是一个django.urls.path的序列()或django.urls.re_path()实例。
- Django按顺序遍历每个URL模式,并在匹配请求的URL的第一个模式停止。
- 如果成功匹配到其中一个URL模式,Django就会导入并调用给定的视图。
- 如果没有URL模式匹配,或者在此过程中的任何点期间引发异常,Django将调用适当的错误处理视图。
path()
path(route, view, kwargs=None, name=None)
- route:应该是一个字符串,其中包含一个URL模式;按顺序依次匹配列表中的项,直到找到匹配的项;
- view:相对应的视图;
- kwargs:任意个关键字参数可以作为一个字典传递给目标视图;
- name:为你的URL取名能使你在Django的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个URL模式。
还可以从URL捕获数据,使用尖括号<数据类型: 参数名>,捕获的值可以选择数据类型。
当匹配到这个URL时,尖括号所匹配的内容会赋给定义的参数,然后传递给对应的视图,并且视图中必须添加相同名称的参数。
例如请求/articles/2005/03/与列表中的第三个条目匹配。Django会调用该函数views.month_archive(request, year=2005,month=3, content='ahhh')
from django.urls import path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), path('articles/<int:year>/', views.year_archive), path('articles/<int:year>/<int:month>/', views.month_archive, {'content': 'ahhh'}), path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail), ]
正则表达式
re_path(route, view, kwargs=None, name=None)
- route:应该是一个字符串,其中包含与Python的兼容的正则表达式re模块,字符串通常使用原始字符串语法(r' ');
- view, kwargs, name:与path()一样。
from django.urls import path, re_path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), re_path(r'^articles/[0-9]{4}/$', views.year_archive), re_path(r'^articles/[0-9]{4}/[0-9]{2}/$', views.month_archive), ]
1、命名参数
通过(?P<name>pattern)可以从URL获取数据,name组的名称,并且 pattern是要匹配的模式。
当匹配到相关URL时,pattern匹配到的内容作为值赋给name,然后传递给视图。并且视图中必须添加相同键名的参数。
例如请求/articles/2005/03/与列表中的第三个条目匹配。Django会调用该函数views.month_archive(request, year=2005,month=3)
urlpatterns = [ path('articles/2003/', views.special_case_2003), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), ]
2、无名参数
通过(pattern)可以从URL获取数据,不设置组名<name>,将pattern匹配到的内容直接传入给视图,视图必须添加相对应数量的位置参数。
不特别推荐这种用法,因为它更容易在匹配的预期含义和视图的参数之间意外引入错误。
urlpatterns = [ re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), ]
在任何一种情况下,建议在给定的正则表达式中仅使用一种样式。当两种样式混合使用时,将忽略任何未命名的组,并且只将命名组传递给视图函数。
include(module,namespace = None)
- module - URLconf模块(或模块名称)
- namespace(str) - 包含的URL条目的实例名称空间
例如请求/blog/about/与inner中的第二个条目匹配。Django会调用该函数views.about(request, blog_id=3)
# main.py from django.urls import include, path urlpatterns = [ path('blog/', include('inner'), {'blog_id': 3}), #inner中的每一行都会被传入{'blog_id': 3}的参数 ] # inner.py from django.urls import path from mysite import views urlpatterns = [ path('archive/', views.archive), path('about/', views.about), ]
只要在include层级传入自定义参数,那么子URLconf中每一条path都会被传入自定义参数,那么就确定每个视图也都设置了对应的参数。