本篇介绍Django的路由系统。
通过这篇文章,你能了解到:
- Django中的URL是什么?
- 路由分发、命名URL与URL的反向解析
- 名称空间的使用
概述
URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。
URLconf配置
- 基本格式
1 | from django.conf.urls import url |
- Django是如何识别这个URL呢?settings中有设置:
1 | ROOT_URLCONF = '项目名.urls' |
- 在Django2.0中用 re_path 来代替 url
1 | from django.urls import path,re_path |
note:
- urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
- 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
- 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
- 每个正则表达式前面的’r’ 是可选的但是建议加上。
正则表达式
常用规则
- 开头不能加
/
- 从上到下匹配,匹配到一个就执行函数($结尾,防止截胡)
- 使用 r 表示原生字符串,不转义
- ^ $ []{} \d \w ? + * .
- 更多规则详见 正则匹配与Re模块
分组
- 正则中捕获到的参数传递给视图函数
- 将捕获的参数按照位置参数传递给视图
1 | from django.conf.urls import url |
命名分组
?P<name>
- 按照 关键字参数 传递视图
- 更加明确,参数的顺序可以改变,但是这是在牺牲简洁的条件下完成的。
1 | from django.conf.urls import url |
note:捕获的参数永远都是字符串。
路由分发
- include (去包含另一个urlConf)
- ROOT__URLCONF这个配置
1 | urlpatterns = [ |
在前面我们的目标是在urls.py中路由时给view函数传递参数,这是正向的过程。
反向解析:
- 在模板中:使用url模板标签。
- 在Python 代码中:使用django.core.urlresolvers.reverse() 函数。
- 在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。
反向解析是为了得到这个URL,然后使用redirect,href,等等。
命名URL和URL反向解析
静态路由
- 命名
- 设置name参数
- 模板中使用:
- url ‘name参数对应的值’
- py文件:
from django.urls import reverse
reverse('name参数对应的值')
URL命名
在url函数的第四个参数, 设置name 别名
1 | url(r'^blog/$', views.blog, name='blog'), |
反向解析
通过name 拿到 url 路径,如果是在路由分下的情况下,也会把它给带上。
模板中
1 | {% url 'blog' %} ---> 'url地址' # 将来替换成以前写死的地址 |
views中
shortcuts import reverse
快捷键
reverse 最终是在 urls 中
1 | reverse('blog') ---> '/blog/' |
在redirect,可以直接用别名,而不用reverse,它里面写到过这种情况
动态路由
传参
分组:
命名分组:多一种方式
分组
1 | url(r'^blog/([0-9]{4})/([0-9]{2})', views.blogs,name='blogs'), |
模板中
1 | <a href="{% url 'blogs' '2019' '07' %}">xxx</a> |
views文件中
1 | reverse('blogs','2019','07') |
分组与参数要一一对应
命名分组
1 | url(r'^blog/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})', views.blogs,name='blogs'), |
模板中
- 顺序得对应
1 | <a href="{% url 'blogs' '2019' '07' %}">xxx</a> |
views中
1 | reverse('blogs','2019','07') |
分组与参数要一一对应
关键字传参
- 位置顺序不受到限制了
1 | <a href="{% url 'blogs' month='07' year='2019' %}">xxx</a> |
- views中
1 | reverse('blogs',year='2019',month='07') |
名称空间
解决,app下重名而产生的覆盖现象
养成习惯,路由分发后就写namespace
当都起一个相同的别名 name=’home’,这样显示的是后面的
因为从上往下解析,后面的覆盖前面的。所以这样就会产生混淆(反向解析中)。
所以需要用区分namespace,include 有namespace默认参数,修改
反向解析时:
名称空间:别名
根的名称空间:子的名称空间:别名