django之路由
Django路由系统
1.路由匹配
本质:url------>视图函数,背后使用的是正则。
urlpatterns=[ url(r"^index/",views.index) ]
url()函数的第一个参数是正则匹配,传递过来的url匹配上,就去找对应的视图函数。
背后隐藏:Django配合浏览器
url(r"^index/",views.index)
地址栏输入http://127.0.0.1:8000/index,其实并没有匹配上r"^index/"因为少了一个/
301是永久重定向,浏览器一共发了两次请求,
第一次 http://127.0.0.1:8000/index
第二次 http://127.0.0.1:8000/index/
APPEND_SLASH=True,每个请求过来后,找到路由对应的视图直接映射,没有找到视图的url在后面加/进行重定向,还是没有就报错了。
就是此配置做了优化,所以你要遵守规范,路径最后加上/,无论是path函数,或者表单中的action,还是a的href属性。
问题一:那我正则最后不加/不就行了么?
为了兼容不同的浏览器,有的浏览器会自动在url的最后给你加/
此时
url(r"^index",views.index)
地址栏输入http://127.0.0.1:8000/index没毛病,可以匹配到
http://127.0.0.1:8000/index/此时就匹配不到了,立刻报错!
因此为了兼容
地址栏网址拷贝,得到https://www.baidu.com/ 可以看到浏览器背后是有偷偷的在做事。
而web框架只能尽可能的去配合浏览器,是不能去改变浏览器,毕竟浏览器的厂家有很多。
问题二:为什么是r"^index/",而不是r"^/index/"呢?开头怎么不加/,form的action,a的href的开头都加了/
首先工作原理不一样:
r"^index/"是路由匹配,django默认是从/后开始匹配,你再加/就匹配不上了。
form的action和a的href加/是因为浏览器,默认在前面加上ip和端口,路由拿到后也不会匹配前面的那个/
总结:只有路由匹配的开头不加/,其他位置都要加/,包括redirect函数
django2.0的url函数没了,需要re_path()才支持正则。
2.路由分发
settings.py文件中有
ROOT_URLCONF = 'djdemo1.urls' 创建项目后这个总路由就确定了
多个app协同开发时,或者项目功能太多,进行划分的时候,总路由负责加一级路径映射到不同app
不同的app中, 将子路由映射到不同app的视图函数中。
用到了include()函数
path(r"^classes/",include("classes.urls")), 尤其注意此api的参数是字符串,app.urls而不是app.urls.py
3.路由传参
普通传参,必须会的
re_path(r"^classes/",views.index) # 然后在视图函数里面用requests.GET/POST.get(key)的方式获取数据
无名传参+视图函数参数接收
re_path(r"^index/(\d+)/") # 利用正则里面的分组,分组的数据会被提取出来,当做实参传递到视图函数中,不用从requests中获取数据
视图函数中,形参名字随意,利用的位置传参,
def index(request,id_test):
pass
有名传参+视图函数配合接收
re_path(r"^index/(?P<id>\d+)/") # 此时给传递的参数起了一个变量名叫id,不用从requests中获取数据
视图函数的形参名必须和此变量名一致,否则报错,此处用的是关键字参数传参
def index(request,id):
pass
但是!有名传参和无名传参不会混合使用,即便是用*args,**kwargs也不行
4.反向解析
解决痛点:改url,一旦项目需要修改路由的url,那么项目里面所有关于此url的地方全部都要改一遍。
本质:给路由起别名,用别名反向解析路由。
定义别名:
re_path(r"^index/(\d+)/",views.index,name="index")
涉及路由分发时的定义
总路由
re_path(r"^index/",include("classes.urls"))
app路由
re_path(r"^classes/(\d+)/",name="class_index") # 在子路由后面加name
使用范围:
视图函数中,用reverse("别名")的方式
模板文件件,用{% url "别名" %}的方式
进阶:带参反向解析
视图函数中:
无名传参反向解析,reverse("别名",args=(name,age,))
有名传参反向解析,reverse("别名",kwargs={"name":name,"age":age})
模板文件中:
<a href="{% url "别名" 参数1 参数2 %}">
至于你再视图函数中用,还是在模板函数中用,看你自己的了。
5.伪静态
目的为了更高的seo,只要把utl末尾加上.html即可。
在路由上面下功夫
re_path(r"^index/(\d)+.html$",views.index)
6.名称空间
完全可以避免,只要起别名的时候前缀加app名即可。
不用看。