django之路由层
目录
路由层
1.路由匹配
path('网址后缀',函数名)
一旦网址后缀匹配上了就会自动执行后面的函数
并结束整个路由的匹配
ps:ip和端口号后面必须要加斜杠的
不加斜杠去请求访问的时候原理
首先它会去查看一遍有没有这个地址,然后发现没有,301是重定向的状态码,那么此时它会考虑给加一个 斜杠去重新执行一次,所有就有了两次
路由结尾的斜杠
默认情况下不写斜杠 django会做二次处理
第一次匹配不上,会让浏览器加斜杠再次请求
django配置文件中可以指定是否自动添加 斜杠
APPEND_SLASH = False(默认是Ture,改为False的时候,不加斜杠的话就不能访问到页面)
2.path转换器
正常情况下很多网站都会有很多相似的网址,如果我们每一个单独开设路由不合理
动态匹配转换器只有在django2X及以上才会有
当网址后缀不固定的时候 可以使用转换器来匹配
'str':匹配除路径分隔符外的任何非空字符串
'int':匹配0或者任意正整数
slug:匹配任意一个由字母或数字组成的字符串
uuid:匹配格式化后的UUID
path:能够匹配完整的URL路径
ps:还支持自定义转换器(自己写正则表达式匹配更加细化的内容)
# 转换器将对应位置匹配到的数据转换成固定的数据类型
path('index/<str:info>/', view.index_func), # index_func(实参request对象, info='转换器匹配到的类型转换之后的内容')
path('index/<str:info>/<int:id>/', view.index_func) # ndex_func(实参request对象, info='转换器匹配到的类型转换之后的内容', id='转换器匹配到的类型转换之后的内容')
3.re_path正则匹配
re_path('test', view.test),
re_path('testadd', view.testadd),
输入网址:http://127.0.0.1:8000/testadd的时候,返回的是test的内容,正则匹配的特点是我们输入的网址的后缀,它会去匹配,只要能匹配到这个后缀的,就算是匹配上了
1.怎么取区分开呢?
re_path('test/', views.test),
re_path('testadd/', view.testadd),
加上/后它完整的是test/,所有它只能匹配到他自己的
2.但是还存在问题
http://127.0.0.1:8000/wfdrfffg/test/egddddddd/6ygg
这个样子还能匹配到,不太精确
那么如果想要使用正则去匹配的话,最好在前面加上^,在后面加上$
re_path('^test/$', views.test),
3.re_path(正则表达式,函数名)
一旦网址后缀的正则能够匹配到内容就会自动执行后面的函数
并结束整个路由的匹配
当网址后缀不固定的时候,可以使用转换器来匹配
4.正则匹配之无名/有名分组
-
无名分组
re_path('^test/(\d{4})', biews.test) 会将括号内正则匹配到的内容当做位置参数传递给视图函数
-
有名分组
re_path('^test/(?P<year>\d{4})/', views.test) 会将括号内正则匹配到的内容当做关键字参数传递给视图函数
注意上述的分组不能混合使用!!!
5.django版本区别
在django1X中,只支持正则匹配,并且方法是url()
django2X及以上中 方法为path()、re_path()等价于url()
反向解析
1.什么是反向解析
当路由频繁变化的时候,html界面与后端上的连接地址如何做到动态解析?
根据自己设置的一个别名,动态解析出一个结果,该结果可以直接访问对应的url
2.反向解析概念
通过一些方法得到一个结果,该结果可以直接访问对应的url触发视图函数
实现url路由动态变化
1.反向解析路由配置
路由匹配关系起别名
path('login/', views.login, name='login_view')
2.html页面上模板语法
{% url 'login_view' %}
3.后端语法
首先导入模块reverse
from django.shortcuts import render, HttpResponse,redirect, reverse
reverse('login_view')
3.动态路由的反向解析
1.当路由出现无名有名分组反向解析需要传递额外的参数
2.无名有名分组反向解析,目的就是需要给一个参数,如果有多个就是需要手动的给多个,这多个参数一般情况都是当前操作数据的主键值。
path('func1/<str:others>/', views.func1_func, name='func1_view')
html页面上的模板语法
{% url 'func1_view' 'jaosn' %}
后端语法
reverse('func1_view', args=('hhh',))
路由分发
1.django是专注与开发应用的,当一个django项目特别庞大的时候,所有的路由与视图函数映射关系全部写在项目名下的urls.py(总路由层),很明显太冗余也不便于管理,这个时候可以利用路由分发来减轻总路由的压力
2.django的每一个应用(app)都可以有自己独立的urls.py路由器,static文件夹,templates文件夹。
3.基于上述特点,使用django做分组开发非常的简便。每个人只需要写自己的应用即可,互不干扰。最后由组长统一汇总到一个空的django项目中然后使用路由分发将多个应用关联在一起,即可完成大项目的拼接。
路由分发解决的就是项目的总路由匹配关系过多的情况
利用路由分发之后,总路由不再直接干路由与视图函数的直接对应关系
总路由而是做一个分发处理(识别当前url是属于那个应用下的,直接分发对应的应用去处理)
请求来了之后,总路由不做对应关系,只询问你要访问哪个app的功能,然后将请求转发给对应的app去处理
提前创建好应用app01与app02然后记得注册
1.总路由配置
# 1.需要导入一个include路由分发模块
from django.conf.urls import url,include
# 2.导入子路由的urls(重名问题 起别名)
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
path('admin/', admin.site.urls),
# 路由分发
path('app01/', include(app01_urls)), # 只要url前缀是app01开头 全部交给app01下的urls处理
path('app02/', include(app02_urls)) # 只要url前缀是app02开头 全部交给app02下的urls处理
]
2.名称空间
路由分发之后,针对相同的别名能否自动反向解析出不同的应用前缀?
默认情况下是无法直接识别应用前缀的
方式1:名称空间
# 总路由增加一个名称空间
path('app01/', include(('app01.urls', 'app01'), namespace='app01')), # 创建名称空间app01
path('app01/', include(('app01.urls', 'app02'), namespace='app02')), # 创建名称空间app02
# 子路由app01
urlpatterns = [
path('after/',views.after, name='after_view')
]
# 后端
def reg(request):
print(reverse('app01:after_view'))
return HttpResponse('下午好 from app01')
# 前端
{% url 'app01:after_view' %}
方式2:起别名(别名不冲突即可)
多个应用别名不冲突可以用应用名作为别名的前缀
# 子路由app01
urlpatterns = [
path('after/',views.after, name='app01_after_view')
]
# 后端
def reg(request):
print(reverse('app01_after_view'))
return HttpResponse('下午好 from app01')
# 前端
{% url 'app01:after_view' %}
1.其实只要保证名字不冲突就没有必要使用名称空间
2.一般情况下,有多个app的时候我们在起别名的时候会加上app的前缀
这样的话就能够确保多个app之间名字冲突的问题