django请求生命周期
- django请求生命周期流程图
- 1.路由层
- 2.视图层
- 3.模板层
- 4.模型层
- 5.django插件
- 6.django中间件
- 7.过程描述
1.浏览器发送请求(默认基于HTTP协议) 2.WSGI创建socket服务端,接收请求(Httprequest),拆解数据 wsgiref、uwsgi都是基于WSGI协议开发出来的 3.拿到拆解的数据,交给django后端,进入django中间件层层筛选,将数据交给路由层 4.在路由层完成地址的匹配,交与视图层 5.在视图层执行核心业务逻辑 6.如果项目前后端结合,则进入模板层,在模板层中可能用到数据库内的数据,拿到模板,前往模型层 7.进入模型层,模型层与数据库进行交涉,连接数据库 8.拿到数据库数据返回模型层 9.从模型层到视图层拿到模板语法直接返回到中间件,再次判断 符合安全规定 10.交给web网关接口进行打包,发送个浏览器, 11.浏览器进行接收
路由匹配
urls.py里面 path('网址后缀',函数名) 一旦网址后缀匹配上就会自动执行后面的函数,并结束整个路由的匹配
- 1.路由结尾
对于路由结尾默认情况下不写斜杠,django会自动做二次处理 * 第一次不加斜杠如果没有匹配到网址后缀会让浏览器加斜杠后再次请求 当然我们也可以控制输入的网址是否自动加斜杠匹配,在django的settings文件内写入 * APPEND_SLASH = False - 2.path转换器
- 2.1 当我们无法确定自己的网址后缀(网址后缀不固定)时,可以使用转换器来匹配网址后缀
'int': IntConverter(), # 常用 'path': PathConverter(), 'slug': SlugConverter(), 'str': StringConverter(), # 常用 'uuid': UUIDConverter(), path('func/<int:year>/<str:info>/',views.func) # 使用转换器会对视图函数产生影响 # 转换器匹配到的内容需要当作视图函数的关键字参数传入 # 转换器有几个,视图函数的参数就必须有几个 def func(request,year,info): pass- 2.2 re_path正则匹配
使用方式: re_path(正则表达式,函数名) #函数名是一个视图函数地址 一旦网址后缀的正则能够匹配到内容就会自动执行后面的函数 然后结束整个路由的匹配 re_path('^test/$', view.test) 当网址后缀不固定时可以使用转换器来匹配- 2.3 正则匹配无名分组
re_path('^test/(\d+)/', views.test) 正则表达式匹配到的内容会当作视图函数的位置参数传递给视图函数- 2.4 正则匹配有名分组
re_path('^test/(?P<year>\d+)/(?P<others>.*?)/', views.test) 正则表达式匹配到的内容会当做视图函数的关键字参数传递给视图函数 - 3.django中正则匹配的区别
在django1.11中只支持正则匹配,方法是: url() 在django2之后:只有path(),re_path() # re_path()等价于django1中的url()
反向解析
页面上提前写死了很多路由,一旦路由发生变化会导致所有的页面相关链接失效,针对此类问题的解析需要使用反向解析
- 1.什么时反向解析
- 返回一个结果,该结果可以访问对于的路由
- 2.路由对应关系起别名
path('register/',views.reg,name='reg_view') - 3.反向解析语法的使用
前端HTML网页: {% url 'reg_view' %} 后端: from django.shortcuts import reverse reverse('reg_view')
针对于无名解析,在path(),re_path(),url()中的操作是相同的
- 4.有名无名反向解析
path('reg/<str:info>/', views.reg, name='reg_view') # 当路由中有不确定的匹配因素 反向解析的时候需要人为给出一个具体的值 reverse('reg_view', args=('jason',)) {% url 'reg_view' 'jason' %}
路由分发
- 1.django中的应用都可以有自己独立文件
urls.py、templates文件夹、static文件夹
为什么要路由分发? 为了能够让基于django开发的多个应用完全独立,便于小组开发 当项目特别大 应用特别多的时候 可以使用路由分发
- 2.总路由负责将指明道路,子路由负责操作数据
总路由: path('app01/', include('app01.urls')), path('app02/', include('app02.urls')), 子路由 path('after/', views.after) # app01 path('after/', views.after) # app02
django名称空间
- 1.有路由分发场景下多个应用在涉及到反向解析别名冲突的时候无法正常解析
解决方式1: *名称空间 namespace path('app01/', include(('app01.urls', 'app01'), namespace='app01')) path('app01/', include(('app01.urls', 'app02'), namespace='app02')) 解决方式2: * 别名不冲突即可 * 保证django项目下没有重复的别名即可