django之url路由系统
URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。
我们就是以这种方式告诉Django,遇到哪个URL的时候,要对应执行哪个函数。
URLconf配置
在settings.py中有根路由的配置
ROOT_URLCONF = 'mysite.urls'
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图,参数,别名),
]
# url(regex, view, kwargs=None, name=None)
参数说明:
- 正则表达式:一个正则表达式字符串。
- views视图:一个可调用对象,通常为一个视图函数
- 参数:可选的要传递给视图函数的默认参数(字典形式)
- 别名:一个可选的name参数
from django.urls import path,re_path 2.0版本中re_path和1.11版本的url是一样的用法。
路由正则
URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。
URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POST
、GET
、HEAD
等等 —— 都将路由到相同的函数。
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<monthr>[0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
^ $ [0-9] [a-zA-Z] \d \w .
{} * + ?
- urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
- 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
- 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
- 每个正则表达式前面的'r' 是可选的但是建议加上。
# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
APPEND_SLASH=True
分组和命名分组
每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图
分组
url(r'^blog/([0-9]{4})/$', views.blogs), —— 》 分组 将捕获的参数按位置传参传递给视图函数
命名分组
url(r'^blog/(?P<year>[0-9]{4})/$', views.blogs), —— 》 命名分组 将捕获的参数按关键字传参传递给视图函数
视图函数指定默认值
# urls.py中
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]
# views.py中,可以为num指定默认值
def page(request, num="1"):
pass
传递视图函数的额外参数
django.conf.urls.url()
可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。
当传递额外参数的字典中的参数和URL中捕获值的命名关键字参数同名时,函数调用时将使用的是字典中的参数,而不是URL中捕获的参数。
urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
views.year_archive(request, year='2005', foo='bar')
路由分发include
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls')),
]
app01.urls
from django.conf.urls import url
from . import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^blog/$', views.blog),
url(r'^blog/(?P<year>[0-9]{4})/(?P<month>\d{2})/$', views.blogs),
]
访问地址,app01/blog/2003/12
URL的命名和反向解析
静态路由
url(r'^blog/$', views.blog, name='blog'),
反向解析
模板
{% url 'blog' %} => /blog/
py文件中
from django.urls import reverse
reverse('blog') => '/blog/'
分组
url(r'^blog/([0-9]{4})/(\d{2})/$', views.blogs, name='blogs'),
反向解析
模板
{% url 'blogs' 2012 12 %}" ——》 /blog/2012/12/
py文件中
from django.urls import reverse
reverse('blogs',args=('2012','12')) ——》 /app01/blog/2012/12/
命名分组
url(r'^blog/([0-9]{4})/(\d{2})/$', views.blogs, name='blogs'),
反向解析
模板
{% url 'blogs' 2012 12 %}" ——》 /blog/2012/12/
{% url 'blogs' year=2012 month=12 %}" ——》 /blog/2012/12/
py文件中
from django.urls import reverse
reverse('blogs',args=('2012','12')) ——》 /app01/blog/2012/12/
reverse('blogs',kwargs={'year':'2012','month':'06'}) ——》 /app01/blog/2012/12/
命名分组可以使用按位置传参,也可以使用关键字传参。
命名空间namespace
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
]
反向解析
模板
{% url 'app01:blogs' 2012 12 %}
py文件中
reverse('app01:blogs',args=('2012','12'))