django之路由层

路由层

1.路由匹配

path('网址后缀',函数名)
	一旦网址后缀匹配上了就会自动执行后面的函数
    并结束整个路由的匹配
ps:ip和端口号后面必须要加斜杠的

image

image

不加斜杠去请求访问的时候原理

首先它会去查看一遍有没有这个地址,然后发现没有,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项目中然后使用路由分发将多个应用关联在一起,即可完成大项目的拼接。

image

路由分发解决的就是项目的总路由匹配关系过多的情况
利用路由分发之后,总路由不再直接干路由与视图函数的直接对应关系
总路由而是做一个分发处理(识别当前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处理
]

image

image

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之间名字冲突的问题
posted @ 2022-12-12 19:38  dear丹  阅读(34)  评论(0编辑  收藏  举报