流程
Django处理接收到URL的流程:
- 首先确定使用的URLconf模块,默认情况下使用的是
settings.py
中ROOT_URLCONF
对应的模块。如果接收到的HttpRequest经由middleware配置了urlconf
属性的话,就会使用该属性配置的模块。 - Django在该模块中查找
urlpatterns
变量,这个变量必须是django.urls.path()
或者django.urls.re_path()
实例。 - Django按顺序匹配
urlpatterns
中的模式,使用首先匹配到的模式。 - 匹配到模式后,会执行该模式对应的视图函数,或者视图类,并把以下参数传递过去:
- HttpRequest实例
- 如果匹配到的模式没有返回named group的话,则正则表达式返回的匹配内容就会作为positional arguments。
- 路径表达式匹配到的named part作为keyword arguments,会被
django.urls.path()
和django.urls.re_path()
所指定的kwargs所覆盖。
- 如果没有匹配到模式,或者处理过程中抛出了异常,则Django会调用处理异常的视图。
示例
URLconf的示例:
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),
path('articles/<int:year>/<int:month>/<slug:slug', views.article_detail)
]
path字符串中,可以使用<>
获取符合条件的字符串,转换成对应数据类型传递给views处理函数中的变量名,例如<int:year>
匹配int类型的变量,传递给views处理函数中的year
变量。如果没有提供数据类型的话,则直接把对应字符串传递下去(不包括/
)。注意路径不需要加/
前缀。
路径匹配类型包含以下几种:
str
:匹配去除/
后的非空字符串,这是默认的匹配方式。int
:匹配非零整数,返回int
类型数据。slug
:匹配由ASCII字母或数字、以及-
和_
组成的字符串。uuid
:匹配格式化的UUID,即必须包含-
,字母小写。path
:匹配包含/
的非空字符串。
URLconf转发
URLconf中的path
可以直接将路径请求发送给对应的视图函数进行处理,也可以转发给另一个URLconf,使用include
函数设置要转发的URLconf,子URLconf接收到的是匹配过后的余下字符串。
URLconf转发可以是同模块中的封装,将同个路径前缀的进行封装处理;同时也可以转发给其他URLconf,转发方式是给include
函数中传递模块的路径字符串:
from django.urls import include, path
from app.main import views as main_views
from credit import views as credit_views
# 另外封装一个pattern,统一处理credit/路径
credit_patterns = [
path('reports/', credit_views.report),
path('reports/<int:id>', credit_views.report),
path('charge', credit_views.charge)
]
urlpatterns = [
path('', main_views.home),
# 转发给其他URLconf
path('help/', include('apps.help.urls')),
path('credit/', include(credit_patterns))
]
# 又或者可以直接传递数组给include
urlpatterns = [
path('', main_views.home),
path('help/', include('apps.help.urls')),
path('credit/', include([
path('reports/', credit_views.report),
path('reports/<int:id>', credit_views.report),
path('charge', credit_views.charge)
]))
]
额外参数
在path()
函数中,不仅可以获取请求路径作为参数传递给视图函数,还可以传递关键字参数给视图函数,例如:
from django.urls import path
from . import views
urlpatterns = [
# 传递给视图函数
path('blog/<int:year>/', views.year_archive, {"foo": "bar"})
# 传递给其他URLconf,注意其下的所有path都会接收到这个关键字参数
path('blog/<int:year>/', include('apps.help.urls'), {"foo": "bar"})
]
关键字参数的优先级比捕获的请求路径参数高。