Django框架:4、视图层之路由匹配、转换器、正则匹配、路由反向解析、路由分发、名称空间
二、Django路由层
路由层是指Django框架目录下的urls.py文件,该文件中存储了网址后缀对应的功能函数
网址:路由
解析成:IP:端口号
网址后缀:路由后缀
eg:https://taobao.com/search/
解析成:IP:端口号/search/
1、路由匹配
版本问题
django2.X及以上版本,path第一个参数写什么就会匹配什么
django1.X版本,第一个参数是正则表达式(以正则的方式匹配)
后缀斜杠问题
无论什么版本django都自带加斜杠后缀的功能,可以通过代码手动取消
settings.py 配置文件中
APPEND_SLASH = False # 手动添加此行代码
2、转换器
转换器:将对应位置匹配到的数据转换成固定格式的数据类型
正常情况下,很多网站都会有很多相似的网址,如果我们每一个都单独开设路由,这样很不合理
Django2.X及以上版本路由动态匹配有五种转换器
str:匹配除路径分隔符外的任何非空字符串。
int:匹配0或者任意正整数。
slug:匹配任意一个由字母或数字组成的字符串。
uuid:匹配格式化后的UUID。
path:能够匹配完整的URL路径
path('index/<str:info>/', views.index_func)
# index_func(实参request对象,info='转换器匹配到的类型转换之后的内容')
path('index/<str:info>/<int:id>/', views.index_func)
# index_func(实参request对象,info='转换器匹配到的类型转换之后的内容',id='转换器匹配到的类型转换之后的内容')
3、正则匹配
Django2.X及以上版本存储路由和视图对应关系的方法默认是PATH方法,PATH方法不支持正则,需要使用re_path,该方法第一个参数是正则
Django1.X版本默认使用的方法是url来匹配路由和视图的对应关系,和re_path的方法一致
正则匹配本质
本质是只要第一个正则表达式能够从用户输入的路由中匹配到数据就算匹配成功会立即停止路由层其他的匹配,直接执行匹配成功的路由执对应的视图函数
解决方法
使用^和$固定匹配开始和结束位置
re_path('^login/$', views.test)
正则匹配无名、有名分组
无名分组
re_path('^test/(\d{4})/', views.test)
会将括号内正则匹配到的内容当做位置参数传递给视图函数
有名分组
re_path('^test/(?P<year>\d{4})/', views.test)
会将括号内正则匹配到的内容当做关键字参数传递给视图函数
'''
注意事项:
无名和有名分组不能混合使用
'''
4、反向解析
通过一个名字可以反向解析出一个结果 该结果可以访问到某个对应的路由
基本使用
1.路由匹配关系起别名
path('login001/', views.login, name='login_view')
2.反向解析语法
html页面上模板语法 {% url 'login_view' %}
后端语法 reverse('login_view')
动态路由的反向解析
path('func1/<str:others>/', views.func1_func, name='func1_view')
html页面上模板语法
{% url 'func1_view' 'jason' %}
后端语法:
需要导入reverse方法
reverse('func1_view', args=('嘿嘿嘿',))
5、路由分发
django可以创建多个应用,并且支持每个应用拥有自己独立的路由层、静态文件、模板层。基于该特性,多人开发项目就可以做到完全解耦合,之后还可以利用路由分发将多个应用下的路由整合到一起
使用方法
1、在app目录下创建子urls.py文件
2、导入所需模块和该app对应视图文件
3、直接在该urls文件下填写路由和视图对应关系
4、在django目录下主urls.py文件下导入子urls.py文件
5、将在该文件下存储路由和子urls文件对应关系
使用路由分发之前 总路由直接干路由与视图函数的匹配
path('index/', index)
使用路由分发之后 总路由只按照应用名分配匹配方向
path('app01/', include('app01.urls'))
6、名称空间
路由分发之后,针对相同的别名能否自动反向解析出不同的应用前缀
针对相同名称的路由识别的方式有两种:
方式一:名称空间
总路由
path('app01/', include(('app01.urls', 'app01'), namespace='app01')),
path('app02/', include(('app02.urls', 'app02'), namespace='app02')),
反向解析
reverse('app01:index_view')
reverse('app02:index_view')
方式二:名称不起冲突
多个应用别名不冲突可以用应用名作为别名的前缀
path('index/', views.index, name='app01_index_view')
path('index/', views.index, name='app02_index_view')