Django通过将传入的URL路径路由到视图函数来处理请求。视图功能负责将响应返回给发出请求的客户端。不同的URL通常由不同的视图功能处理。要将请求路由到特定的视图功能,Django会查看您的URL配置(或简称URLconf)。默认项目模板在中定义URLconf <myproject>/urls.py。
您的URLconf应该是一个python模块,该模块定义了名为的属性urlpatterns,该属性是实例的列表。每个实例至少必须定义一个正则表达式(正则表达式)以与URL匹配,并定义一个目标,该目标可以是视图函数或不同的URLconf。如果URL模式以视图函数为目标,则最好给它起一个名称,以便以后轻松引用该模式。django.conf.urls.url()url()
让我们看一个基本的例子:
# In <myproject>/urls.py from django.conf.urls import url frommyapp.viewsimport home, about, blog_detail urlpatterns = [ url(r'^$', home, name='home'), url(r'^about/$', about, name='about'), url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'), ]
这URLconf中定义了三个URL模式,所有指定的视图:home,about和blog-detail。
url(r'^$', home, name='home'),
正则表达式包含一个开始锚“ ^”,紧随其后是一个结束锚“ $”。该模式将匹配网址路径为空字符串的请求,并将其路由到中home定义的视图myapp.views。
url(r'^about/$', about, name='about'),
此正则表达式包含一个开始锚点,后跟文字字符串about/和结束锚点。这将匹配URL/about/并将其路由到about视图。由于每个非空URL都以开头/,因此Django会为您方便地剪切第一个斜杠。
url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),
这个正则表达式有点复杂。blog/像前面的模式一样,它定义了起始锚和文字字符串。下一部分(?P<id>\d+)称为捕获组。捕获组,顾名思义,捕获了一部分字符串,而Django将捕获的字符串作为参数传递给view函数。
捕获组的语法为(?P<name>pattern)。name定义组的名称,这也是Django用于将参数传递给视图的名称。该模式定义该组匹配哪些字符。
在这种情况下,名称为id,因此该函数blog_detail必须接受名为的参数id。模式是\d+。\d表示该模式仅与数字字符匹配。+表示模式必须匹配一个或多个字符。
一些常见的模式:
模式 | 用于 | 火柴 |
---|---|---|
\d+ | ID | 一个或多个数字字符 |
[\w-]+ | sl | 一个或多个字母数字字符,下划线或破折号 |
[0-9]{4} | 年(长) | 四个数字,从零到九 |
[0-9]{2} | 今年(短) 月 月的一天 | 两个数字,从零到九 |
[^/]+ | 路径段 | 除斜杠外的所有内容 |
模式中的捕获组blog-detail后跟一个literal/和结尾锚。
有效的URL包括:
/blog/1/ # passes id='1'
/blog/42/ # passes id='42'
无效的URL例如:
/blog/a/ # 'a' does not match '\d'
/blog// # no characters in the capturing group does not match '+'
Django按照在中定义的相同顺序处理每个URL模式urlpatterns。如果多个模式可以匹配同一URL,则这一点很重要。例如:
urlpatterns = [ url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'), url(r'blog/overview/$', blog_overview, name='blog-overview'), ]
在上面的URLconf中,第二个模式不可访问。该模式将与URL匹配/blog/overview/,但是blog_overviewURL会首先与该blog-detail模式匹配并blog_detail使用参数调用视图,而不是调用视图slug='overview'。
为确保将URL/blog/overview/路由到blog_overview视图,应将模式放在blog-detail模式上方:
urlpatterns = [ url(r'blog/overview/$', blog_overview, name='blog-overview'), url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'), ]