Django路由系统
Django路由系统
1.路由系统
-
URl配置(URLconf)就像Django所支撑网站的目录,它的本质是URL与该URL调用的视图函数之间的映射关系
2.URLconf配置
-
基本格式
-
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图,参数,别名),
]
-
-
参数说明:
-
正则表达式:一个正则表达式字符串
-
views视图: 一个可调用对象,通常为一个视图函数\参数: 可选的要传递给视图函数的默认参数(字典形是)
-
别名: 一个可选的name参数
-
-
2.0版本的django格式
-
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),
] -
其中re_path与1.11版本的url是一样的用法
-
3.正则表达式详解
-
基本配置
-
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/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), -
注意事项
-
urlpatterns中的元素哪找书写顺序从上往下逐一匹配正则表达式,一旦匹配成功就不在继续
-
若要从URL中捕获一个值,只需要在它的周围放置一对圆括号<>(分组匹配)
-
不需要添加提个前导的反斜杠,因为每个URL都有,例如应该是^articles而不是^/articles
-
每个正则表达式前面的'r'是可选的,但是建议加上
-
-
补充说明
-
APPEND_SLASH=True
-
django settings.py配置文件中没有这个参数,但是Django默认这个参数为True,其作用就是自动的在网址的末尾加"/“
-
如果设定其为False,当访问网页时不自己加" / ",就会提示找不到该页面
-
-
4.分组命名匹配
-
分组匹配使用简单的正则表达式通过圆括号来捕获URL中的值并以位置参数的形式传递给视图,
-
更高级的是以分组命名匹配的正则表达式来捕获URl的值,并以关键字参数的方式传递给视图
-
from django.conf.urls import url
from . 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),
] -
与前面的示例的不同就在于捕获的值作为关键字参数而不是位置参数传递给视角函数
-
例如,针对URL /articles/2017/12/相当于按以下方式调用视图函数:
-
views.month_archive(request, year="2017", month="12")
-
优点:让你的URLconf更加清晰明确且不容易产生参数顺序问题的错误,
-
缺点: 语法犯了罪,因为丑是原罪
-
-
URLconf匹配的位置
-
URLconf在请求的URL上查找,将它当做一个普通的Python字符串,不包括GET和POST参数以及域名
-
例如,http://www.example.com/myapp/ 请求中,URLconf 将查找 /myapp/ 。
在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找 /myapp/ 。
-
URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的
POST
、GET
、HEAD
等等 —— 都将路由到相同的函数。
-
-
捕获的参数永远都作为一个普通的字符串传递给视图,无论正则表达式用什么匹配方式
5.视图函数
-
视图函数中指定默认值
-
# 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模式指向的是同一个视图函数,但是第一个模式没有捕获任何东西,当他匹配上了,默认num = '1',如果第二个模式匹配上了,num将等于正则表达式捕获到的num值
-
传递额外的参数给视图参数
-
URLconfs 具有一个钩子,让你传递一个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'}),
]
-
-
-
6.路由分配
-
可以找到其他app下的URLconf
-
include其他的URLconfs
-
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('app01.urls')), # 可以包含其他的URLconfs文件
]
-
7.命名URL和URL反向解析
-
使用Django项目时,一个常见的需求就是获取URl的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URl等,或用于处理服务器端的导航(重定向)
-
Django提供一个方法是让URL映射是URl设计唯一的地方,你填充你的URLconf,然后可以双向使用他:
-
根据用户/浏览器发起的URL请求,它调用正确的Django视图,并从URL中提取它的参数需要的而值
-
根据Django视图的标识和将要传递给它的参数的值,获取与之关联的URL,这就是反向解析URL,反向URL匹配,反向URL查询或简单的URL反查
-
-
在需要URL的地方,对于不同的层级,Django提供了不同的工具用于URL反查
-
在模板中:使用URL模板标签
-
在Python代码中:使用django.core.urlresolvers.reverse() 函数。
-
在更高层的与处理Django相关模型实例相关代码中,使用get_absolute_url()方法
-
-
总结:简单的说就是可以给我们的URL匹配规则起一个名字,一个规则一个名字,这样就可以通过名字来调用当前的URL
-
例如:
-
url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home
url(r'^index/(\d*)', views.index, name='index'), # 给我的url匹配模式起名为index
-
在模板中可以这样用
-
{% url 'home' %}
-
-
在views函数中可以这样引用
-
from django.urls import reverse
reverse("index", args=("2018", ))
-
-
在某些场景中,一个视图是可以通用的,所以在URL和视图之间存在一对多的关系,对于这些情况,只有视图的名字还不厚
-
-
注意
-
为了完成上面例子中的URL 反查,你将需要使用命名的URL 模式。URL 的名称使用的字符串可以包含任何你喜欢的字符。不只限制在合法的Python 名称。
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。如果你的URL 模式叫做
comment
,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用
myapp-comment
而不是comment
。
-
8.命名名称空间
-
即使在不同APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL
-
语法:
-
'命名空间名称:URL名称'
模板中使用:
{% url 'app01:detail' pk=12 pp=99 %}
views中的函数中使用
v = reverse('app01:detail', kwargs={'pk':11})
这样即使app中URL的命名相同,我也可以反转得到正确的URL了。
-
-