URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。
我们就是以这种方式告诉Django,遇到哪个URL的时候,要对应执行哪个函数。
URLconf配置 :
from django.conf.urls import url urlpatterns = [ url (正则表达式, view视图, 参数, 别名), ]
示例 :
from django.conf.urls import url from app import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ] _______________________________________________________________ django 2.0版本的路由系统是下面的写法 : from django.urls import path,re_path 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), ]
参数说明 :
正则表达式 : 一个正则表达式字符串
view视图 : 一个可以调用对象, 通常为一个视图函数
参数 : 可选的要传递给视图函数的默认参数(字典形式)
别名 : 一个可选的name参数
正则表达式详解 :
注意事项 :
urlpatterns中的元素按照书写顺序从上到下逐一匹配正则表达式, 一旦匹配成功则不再继续
若要从URL中捕获一个值, 只需要将它用一对圆括号包围起来就好(分组匹配)
不需要添加一个前导的反斜杠, 因为每个URL默认都会有.
每个正则表达式前面的"r"是可选的但是建议写上.
补充 :
# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项 # 将True改为False之后不再自动跳转 APPEND_SLASH=True #Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'
分组命名匹配 :
上面示例中使用简单的正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式传递给视图. 在更高级的用法中, 可以使用分组命名匹配的正则表达式组来捕获URL的值并以关键字参数形式传递给视图. 在python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern)
,其中name是组的名字, pattern是要匹配的模式.
from django.conf.urls import url from app import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ]
这样实现传参的方式和上面的示例基本相同, 只有一个细微的差别: 捕获的值是关键字参数而不是位置参数传递给视图函数.
在实际应用中, 使用分组命名匹配的方式可以让你的URLconf更加清晰且不容易产生参数顺序问题的错误.
URLconf匹配的位置 :
URLconf在请求的URL上查找, 将它当做一个普通的Python字符串. 不包括GET和POST的参数以及域名. URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POST、GET、HEAD等等 —— 都将路由到相同的函数。
例如:
http://www.baidu.com/myapp/ 请求中, URLconf将查找/myapp/
http://www.baidu.com/myapp/?id=1 请求中, URLconf将查找/myapp/
捕获的参数永远为字符串 :
每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图, 无论正则表达式是用什么匹配方式. 传递到视图函数的参数都是一个字符串类型.
视图函数中的指定默认值 :
# 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
在上面的例子中,两个URL模式指向相同的view - views.page - 但是第一个模式并没有从URL中捕获任何东西。如果第一个模式匹配上了,page()函数将使用其默认参数num=“1”,如果第二个模式匹配,page()将使用正则表达式捕获到的num值。
include其他的URLconfs : (路由分发)
from django.conf.urls import include, url urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/', include('blog.urls')), # 可以包含其他的URLconfs文件 ]
传递额外的参数给视图函数 :
URLconf可以传递一个Python字典作为额外的参数传递给视图函数.
django.conf.urls.url()可接收一个可选的第三个参数, 它是一个字典, 表示想要传递给视图函数的额外关键字参数.
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')。
当传递额外参数的字典中的参数和URL中捕获值的命名关键字参数同名时,函数调用时将使用的是字典中的参数,而不是URL中捕获的参数。
命名URL和URL反向解析 :
在使用django项目时, 一个常见的需求是获得URL的最终形式, 以用于嵌入到生成的内容中,
简单来说就是给URL匹配规则起一个名字, 一个URL匹配模式起一个名字.
这样就可以不用写死代码, 只需要通过名字来调用当前的URL.
举个栗子 :
###########url中的映射代码############## url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home url(r'^index/(d*)', views.index, name='index'), # 给我的url匹配模式起名为index
#################模板中的使用代码############## {% url 'home' %}
###############在view函数中使用的代码############### from django.urls import reverse reverse("index", args=("2018", )) #部分代码 ###############args是重定向时, 需要给url中的正则表达式传的参数
命名空间模式 :
即使不同的app使用相同的URL名称, URL的命名空间模式也可以让你唯一反转命名的URL.
举个栗子 :
############project中的urls.py############### from django.conf.urls import url, include urlpatterns = [ url(r'^app01/', include('app01.urls', namespace='app01')), url(r'^app02/', include('app02.urls', namespace='app02')), ]
#################app01中的urls.py################# from django.conf.urls import url from app01 import views app_name = 'app01' urlpatterns = [ url(r'^(?P<pk>d+)/$', views.detail, name='detail') ]
###################app02中的urls.py################## from django.conf.urls import url from app02 import views app_name = 'app02' urlpatterns = [ url(r'^(?P<pk>d+)/$', views.detail, name='detail') ]