Django请求生命周期
1.请求过程
浏览器客户端发起请求
数据经过web服务网关接口拆解数据
中间件处理请求
在路由层根据当前请求的URL找到对应的视图函数
在view视图层中进行业务处理(ORM处理数据先从数据库中拿到数据,处理好后再加载到template对应的页面中然后将数据返回)
再经过中间件处理返回响应
数据经过web服务网关接口对数据进行封装
在浏览器中展示
2.过程图解
路由匹配
1.什么是Django路由匹配
根据用户请求的URL链接来判断对应的处理程序,并返回处理结果
路由配置在urls.py文件中,每一条配置对应相应的处理方法。
Django版本不同对应的urls.py配置也有点不一样
语法结构:
path("网址后缀",函数名)
2.结尾斜杠注意点
在urls.py中定义网址后缀时默认可以不需要加"/"符,Django会进行二次处理:
第一次:直接用默认的查找
第二次:第一遍直接查找没有就会自动给你加上斜杠符再次去查询,如果还是没有那么就救不了你了
当然我们也可以自己来设置是否需要自动帮你添加斜杠,在配置文件中加一行代码:
APPEND_SLASH = False
3.path转换器
当查询网址后缀不固定的时候可以通过path转换器来匹配,path转换器有五种默认方法也支持自定义:
str:匹配任何非空字符串,但不含斜杠(默认使用)
int:匹配0和正整数,返回一个整型数据类型
slug:匹配字母、数字、横杠以及下划线组成的字符串
uuid:匹配格式化的uuid
path:匹配任何非空字符串,包含斜杠
path('func/<int:year>/<str:info>',views.func) '''转换器匹配到的内容会当做视图函数的关键字参数传入, 且视图函数的形参必须与其对应''' def func(request,year,info): pass
4.正则匹配
当转换器用正则表达式捕获值的时候需要用:re_path(),而不是前面的path()
re_path('URL后缀/正则表达式',views.函数名) '''当后缀中正则能匹配到内容就会自动执行后面的视图函数'''
4.1.正则匹配之无名分组
正则匹配时也可以从后缀中匹配多个要求
re_path('URL后缀/正则表达式/',views.函数名) '''正则表达式匹配到的内容会当做视图函数的位置参数传递给视图函数'''
4.2.正则匹配之有名分组
可以给每一个正则匹配到的数据定义个名字
re_path('URL后缀/(?P<别名>正则表达式)/(?P<别名>正则表达式)/)' '''匹配到的内容会起别名后当做视图函数的关键字参数传递给视图参数'''
小Tips:
在Django1.11中 只支持正则匹配 并且方法是 url()
在Django2,3,4版本中 path() re_path() 等价于 url()
反向解析
1.什么是反向解析
页面上的一些超链接、重定向等路由都是写死的,一旦路由发生变化则会导致所有页面相关链接失效,而反向解析就是用来防止出现该问题的。
2.反向解析使用
方式一:路由对应关系起别名
在路由中给对应关系再取一个别名这样网页中使用时直接调用这个别名
路由层: path('后缀',views.视图函数,name='关系名')
方式二:使用反向解析语法
html页面与后端都可以进行调用
html调用: {% url '关系名' %} 后端跳转调用: from django.shortcuts import reverse reverse('关系名')
ps:反向解析的操作三个方法都一样:path()、re_path()、url()
3.有名无名反向解析
如果路由里面有不确定的因素那么在使用反向解析的时候必须人为传递数据,且有几个不确定因素就得穿几个值
eg: 路由层:path('reg/<str:info>',views.reg, name='reg_view') 模块层:reverse('reg_view',args=('aa'),) html页:{% url 'reg_view' 'aa' %}
路由分发
1.什么是路由分发
当一个项目特别大的时候会有很多应用,这所有的应用的路由都写在项目文件内的urls.py文件内就会出现很多问题,同理还有static、templates文件夹。所以为了每个应用能够独立便于小组开发Django中的应用都可以有自己独立的这些文件,由项目的总路由来管理每个应用的子路由。
2.怎么实现
在每个应用文件夹内都创建自己的子路由再由总路由来分发,当项目很大应用很多的时候使用路由分发非常的便于管理
总路由: path('app01/', include('app01.urls')), path('app02/', include('app02.urls')), 子路由: path('name/', views.name) path('name/', views.name) 总路由: path('应用对应的后缀', include('应用文件下的urls文件')) 子路由: path('后缀', 视图函数)
3.名称空间
当多应用使用路由分发后应用与应用之间如果有名字冲突这时候再用反向解析时无法正常的解析
解决方式一:
默认规则再起别名的时候前面带个应用名,因为一个项目中应用名与应用名之间的名字是肯定不会冲突的
解决方式二:
总路由创建名称空间:namespace(复杂)
path('app01/',include(('app01.urls','app01'),namespace='app01')) path('app02/',include(('app02.urls','app02'),namespace='app02'))