django请求生命周期流程与路由层相关知识
请求生命周期流程图
django请求生命周期流程图
路由层之路由匹配
我们都知道,路由层是匹配对应关系用的,那么它是怎么匹配上的呢?
urlpatterns = [
url(r'^index/', views.index),
]
url方法的第一个参数其实是一个正则表达式,只要用户输入的地址后缀与内容匹配上,就会执行对应的视图函数。
并且django有一个二次追加斜杠机制,如果你在输入地址后缀时末尾没有加斜杠,django会先匹配一次,如果匹配不上,那么django还会让浏览器默认加斜杠再次发送请求,比如:
# 第一次匹配
http://127.0.0.1:8000/index
# 匹配不上加斜杠再次发送请求
http://127.0.0.1:8000/index/
如果想要取消这个斜杠机制,那么可以在settings.py加上:
APPEND_SLASH = False
因为是正则表达式,所以比如像上述代码中的例子,我在地址栏输入:
http://127.0.0.1:8000/index/abcde/66
或者:
http://127.0.0.1:8000/index/
都是可以匹配到正则:^index/ 的
拓展
让用户不需要输入地址后缀就可以访问到指定页面:
urlpatterns = [
url(r'^$', views.index),
]
也可以定义一个尾页, 用户输入一个没有对应关系的直接返回:
urlpatterns = [
url(r'.*',views.error),
]
无名有名分组
无名分组
我们都知道,路由匹配成功之后就会调用视图函数,并且默认情况下会自动给视图函数传递一个request位置参数。
但是如果正则表达式中加了括号,那么就不止传递一个request位置参数了,还会传递括号内正则表达式匹配到的内容。
urlpatterns = [
url(r'^index/(.*)', views.index),
]
如果正则加了一个括号,那么视图函数就需要多写一个形参用于接收匹配到的内容,不然会报错。
def index(request, aa):
return HttpResponse(aa)
这个就是无名分组。
有名分组
python中的正则表达式加括号是可以给括号内的内容进行命名的,这里的正则表达式自然也可以。
给括号内的内容命名为address:
urlpatterns = [
url(r'^index/(?P<address>.*)', views.index),
]
给括号内命名后,视图函数就需要一个名字相同的形参接收:
def index(request, address):
return HttpResponse(address)
这个就是有名分组。
补充说明
1.无名分组需要一个形参接收括号内的内容,名字随意。
2.有名分组也需要一个形参接收括号内的内容,名字要与正则表达式里的名字相同。
3.无名分组是位置传参,有名分组是关键字传参。
4.无名分组与有名分组不能混合使用,单个可以重复使用。
反向解析
前言:html中a标签的href可以写网址的全称,也可以写后缀,写后缀会自动补全当前ip和port。
<a href='index'>点我跳转index</a>
<!--href='127.0.0.1:8000/index' -->
如上述标签可以跳转到127.0.0.1:8000/index,但是如果我路由匹配表达式出现了变化,那么这个地址就无法跳转到我想要的页面了,比如:
# 原本
url(r'^index/', views.index)
# 修改后
url(r'^index123/', views.index)
这个时候a标签就失效了,这该如何解决呢?反向解析就可以解决这个问题。
反向解析
通过反向解析可以获取到一个结果,该结果可以访问到一个路由。这么说可能有点模糊,我们来看实战:
第一步:给对应关系起别名
url(r'^index/', views.index, name='index_view')
第二步:使用模板语法修改a标签
<a href="{% url 'index_view' %}">点我跳转index</a>
这个时候随意修改路由的匹配表达式都会不出现a标签无法跳转。
后端也可以查看‘index_view’对应的路由:
from django.shortcuts import reverse
reverse('index_view') # 对应路由
根据这个路由,我们也可以进行重定向:
from django.shortcuts import reverse
def index(request):
return redirect(reverse('index_view'))
无名有名分组反向解析
无名分组反向解析
如果你在设置路由时使用了无名分组,那么你括号内的正则表达式的内容,需要人为指定。比如如下路由:
url(r'^index/(.*)', views.index, name='index_view')
这时候你的a标签需要指定内容,因为对于表达式 '^index/(.*)' 有多种方式匹配到,a标签不知道该使用哪个,所以需要人为指定。
比如我指定括号内的内容为:123
<a href="{% url 'index_view' 123 %}">点我跳转index</a>
后端也需要指定:
from django.shortcuts import reverse
reverse('index_view', args=(123,)) # /index/123
有名分组反向解析
如果你在设置路由时使用了有名分组,那么同理,需要人为指定内容。
路由:命名为address
url(r'^index/(?P<address>.*)', views.index, name='index_view')
a标签:设置address为123,两种方式都可
<a href="{% url 'index_view' 123 %}">点我跳转index</a>
<a href="{% url 'index_view' address=123 %}">点我跳转index</a>
后端:两种方式都可
from django.shortcuts import reverse
reverse('index_view', args=(123,)) # /index/123
reverse('index_view', kwargs=('address':123)) # /index/123
路由分发
如果一个django项目特别庞大,里面有很多应用,每个应用下有很多对应关系,这种情况如果把路由对应关系都写在项目同名文件夹下的urls.py文件下是明显不合理的,所以我们要把路由对应关系拆分开。
django支持每个应用都可以有自己独立的路由层、模板层、静态文件、视图层(默认)、模型层(默认)。
每个应用编写好自己的功能后,最后只需要整合一下就可以了。并且防止出现不同应用中出现相同路由,可以通过应用前缀区分,并且用到一个include方法:
总路由:整个应用app01与app02
from django.conf.urls import url, include
# 导入各个应用的路由,并起别名方便使用
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^app01/', include(app01_urls)),
url(r'^app02/', include(app02_urls)),
]
简写:
from django.conf.urls import url, include
urlpatterns = [
url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls')),
]
此时,访问应用app01下的index就需要这么输入:
http://127.0.0.1:8000/app01/index/
名称空间
不同的应用,设置路由时可能会使用相同的别名,比如:
应用app01路由:
urlpatterns = [
url(r'^index/', views.index, name='index_view'),
]
应用app02路由:
urlpatterns = [
url(r'^index/', views.index, name='index_view'),
]
a标签:
<a href="{% url 'index_view' %}">点我跳转index</a>
<a href="{% url 'index_view' %}">点我跳转index</a>
此时我就无法让我的a标签都可以跳到应用app01下index或者应用app02下index,它只能跳转到其中一个。
解决方法
方法一:总路由添加名称空间
urlpatterns = [
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
]
a标签:
<a href="{% url 'app01:index_view' %}">点我跳转index</a>
<a href="{% url 'app02:index_view' %}">点我跳转index</a>
方式二:应用路由起别名加上应用前缀,如
urlpatterns = [
url(r'^index/', views.index, name='app01_index_view'),
]
从根本解决问题。
django请求生命周期流程与路由层相关知识的更多相关文章
- Django框架10 /sweetalert插件、django事务和锁、中间件、django请求生命周期
Django框架10 /sweetalert插件.django事务和锁.中间件.django请求生命周期 目录 Django框架10 /sweetalert插件.django事务和锁.中间件.djan ...
- Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)
一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- django请求生命周期,FBV和CBV,ORM拾遗,Git
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- Django(35)Django请求生命周期分析(超详细)
Django请求生命周期分析 1.客户端发送请求 在浏览器输入url地址,例如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都 ...
- Django请求生命周期之响应内容
Django请求生命周期: 1.发送http请求2.服务器接受,根据请求头中的url在路由关系表中进行匹配(从上到下)3.匹配成功后,执行指定的views函数 URL -> 函数 ==>F ...
- Django组件 - Django请求生命周期、中间件
一.Django请求生命周期 在学习中间件之前,先了解一下Django的请求生命周期,如下图: 1)client代表浏览器,浏览器内部为我们封装了socket,Django的WSGI模块也封装了soc ...
- Django请求生命周期和ORM
dajngo请求生命周期 django请求生命周期是:当用户在browser点击URL后,在django后台都发生了什么. 请求响应Http 1.发送Http请求 2.服务器接收,根据请求头中url在 ...
随机推荐
- 解决使用 swiper 常见的问题
使用 swiper 的过程中个人总结 1. swiper插件使用方法, 直接查看文档 swiper基础演示 swiper API文档 2.swiper近视初始化时, 其父级元素处于隐藏状态(displ ...
- 移动端的vw px rem之间换算
一.vw px rem em是什么 1.vw:就是相对视口宽度(Viewport Width).1vw = 1% * 视口宽度.也就是说,一个视口就是100vw. 2.px:px应该是在css中使用最 ...
- 驳《我不是很懂 Node.js 社区的 DRY 文化》
今天在群里有人讨论方老师的文章<我不是很懂 Node.js 社区的 DRY 文化>,我也看了一遍,槽点太多,不知道如何下笔. 方老师分析了几个依赖最多的 npm 包,每个都只有不到百行代码 ...
- 关于recyclerview其item数据重复问题
查找方法(query)的list只定义对象,不实例化,等到要添加的时候,再new一个新的对象出来. 千万不要如下图这样,否则item显示出来的永远是最新数据. (这个bug找了两天,还是基本功不扎实, ...
- Go语言 映射(map)
Go语言 映射(map) 1. 什么是 map2. 创建 map3. 访问 map4. nil map和空map5. map中元素的返回值6. len()和delete()7. 测试map中元素是否 ...
- nginx负载均衡的五种方式
文章目录 前言 :负载均衡是什么 一.方式1:轮询 二.方式2:权重 方式3:iphash 方式4:最小连接 方式5:fair 总结:根据这几种方式可以猜测处nginx的底层使用了计数器,从而可以将海 ...
- Spring Boot-@Configuration注解
@Configuration:指明当前类是一个配置类,就是来替代spring的配置文件 @Configuration public class MyConfigFile { @Bean public ...
- 无需debug,通过抽象模型快速梳理代码核心流程
上一篇我们通过DSM来确定了核心对象并构建了抽象模型.本篇是<如何高效阅读源码>专题的第八篇,我们来基于抽象模型来梳理核心流程. 本节主要内容: 如何通过抽象模型来梳理核心流程 从类名和注 ...
- Warmup小记
什么是warmup 热身,在刚刚开始训练时以很小的学习率进行训练,使得网络熟悉数据,随着训练的进行学习率慢慢变大,到了一定程度,以设置的初始学习率进行训练,接着过了一些inter后,学习率再慢慢变小: ...
- Vim 中进行文本替换
Vim 中进行文本替换 格式 用法 :[range]s/from/to/[flags] tips: [] 表示该内容可选 参数 from 需要替换的字符串(可以是正则表达式) to 替换后的字符串 r ...