Django如何处理一个请求
Django系统执行代码算法
-
Django确定使用根URLconf模块。通常是ROOT_URLCONF设置的值,如果传入HttpRequest对象拥有urlconf属性(通过中间件设置),它的值将被用来代替ROOT_URLCONF设置
-
Django加载该python模块并寻找可用urlpatterns。
-
Django一次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来
-
一旦有URL匹配成功,Django导入并调用相关的视图。
-
如果没有URL被匹配,或者匹配过程中出现了异常,Django会调用一个适当的错误处理视图。
示例
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),
]
注意事项:
- 要从URL中取值,使用尖括号
- 捕获的值可以选择性地包含转换器类型
- 这里不需要添加反斜杠,因为每个URL都有
路径转换器
- str 匹配除了"/"之外的非空字符串
- int 匹配0或任何正整数,返回一个int
- slug 匹配任意由ASCII字母或数字以及连字符和下划线组成的段标签(如building-your-1st)
- uuid 匹配一个格式化的UUID
- path 匹配非空字段,保活路径分隔符’/’
使用正则表达式
如果路径和转化器语法不能很好的定义URL模式,可以使用正则表达式re_path()
命名正则表达式的语法(?P<name>pattern)
name是组名,pattern是要匹配的模式
示例
from django.urls import path, re_path
from . import views
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),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]
嵌套参数
正则表达式允许嵌套参数,Django将处理它们并传递给视图
from django.urls import re_path
urlpatterns = [
re_path(r'^blog/(page-(\d+)/)?$', blog_articles), # bad
re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?$', comments), # good
]
例 blog/page-2/将匹配给blog_articles并带有2个参数:page-2/和2。
包含其他的URLconfs
可以使用include包含其他的URLconf模块
示例
from django.urls import include, path
urlpatterns = [
# ... snip ...
path('community/', include('aggregator.urls')),
path('contact/', include('contact.urls')),
# ... snip ...
]
每当Django遇到include(),它会将匹配到该点的URLconf的任何部分切掉,并将剩余的字符串发送到包含的URLconf进行进一步处理。
传递额外选项给视图函数
URLcongf由钩子来允许把其他参数作为Python字典来传递给视图函数。
path()函数可带有可选的第三个参数(必须是字典),传递到视图函数里
示例
from django.urls import path
from . import views
urlpatterns = [
path(‘blog/int:year/’, views.year_archive, {‘foo’: ‘bar’}),
]