python-django中的APPEND_SLASH实现方法


Posted in Python onJune 21, 2019

关于django中的APPEND_SLASH

APPEND_SLASH 它是啥?

看变量名大概能知道做什么,就是添加斜线,用路由系统那里。

路由文件,只写了路由关系代码

......
urlpatterns = [
  url(r'^test/$', views.test),
]
......

APPEND_SLASH这个常量默认为True,就是假如你没有添加斜线,他会帮你添加上(总体是这样,具体得看源码怎么写的了)

执行命名行代码启动django项目

python manage.py runserver

目前APPEND_SLASH=True,我们打开浏览器的开发者工具,查看网络请求,输入127.0.0.1:8000/test 这里我是没有加斜线的

python-django中的APPEND_SLASH实现方法

仔细看下网络请求,我们输入127.0.0.1:8000/test,看起来只发送了一次,其实真实发送了两次请求。

我们继续再访问这个url:127.0.0.1:8000/test11,看看请求

python-django中的APPEND_SLASH实现方法

我们也同样访问了一个url,但是这次和上面不同的是,只发送了一次请求。

两次都是发送一个get请求,访问服务器的一个资源。

第一次请求的url为127.0.0.1:8000/test,我们的路由关系中是没有这个url的,对没错,如果访问想要访问到服务器的资源必须为这样的url才行127.0.0.1:8000/test/,虽说这两个url看起来差不多,但其实差很多的。但是第一次请求的url只需在最后加上/,就能访问到资源了,这就是APPEND_SLASH的作用。

第二次请求的url为127.0.0.1:8000/test11,这个地址也不在我们的路由关系中,况且加上了/,也不能访问到资源。所以总共发送了一次,最终返回了404错误。

先大致总结下:APPEND_SLASH=True的情况下,先会根据前端传来的url,先检测这个url能不能访问资源,如果可以访问的话,那么就去执行相应的业务代码,最后返回。如果这个url不能访问到资源的话,会判断这个url最后有没有/,有/的话,则返回404错误;如果没有/的话,便会帮你加上/,生成一个新的url,再去检测这个新的url能不能访问到资源,如果能访问的话,则返回301的状态码,并将这个新的url传到前端,进行重定向操作(这就是我们第一次请求出现的情况),如果这个新的url(帮你加上/的)还是不能访问到资源的话,也会返回404错误(这就是我们第二次请求出现的情况)。这就是对上面出现情况的总结吧(具体流程还得去看源码)

那么APPEND_SLASH=False的情况,就不会帮你加/,你前台传怎样的url,那就用这个url去访问资源,能不能访问还得看你url对不对。

在走到路由层之前,请求会先走到中间件这一层,在这一层就执行了上面分析的逻辑

这一个中间件实现了上面的逻辑 'django.middleware.common.CommonMiddleware',请求来的时候,会走这个中间件的process_request方法,下面来看这个方法写了什么

python-django中的APPEND_SLASH实现方法

看这一句注释:# Check if a slash should be appended,检测是否需要加上斜线

看这个方法should_redirect_with_slash,返回值为bool类型。返回True的情况是,APPEND_SLASH=True,这个url不是以/结尾的,并且这个url添加上了/,能够访问资源的。必须满足这三种情况,返回值为True,其他情况的话返回就是False。

下面贴上should_redirect_with_slash的源码

def should_redirect_with_slash(self, request):
  """
  Return True if settings.APPEND_SLASH is True and appending a slash to
  the request path turns an invalid path into a valid one.
  """
  if settings.APPEND_SLASH and not request.path_info.endswith('/'):
    urlconf = getattr(request, 'urlconf', None)
    return (
      not is_valid_path(request.path_info, urlconf) and
      is_valid_path('%s/' % request.path_info, urlconf)
    )
  return False

就说下 is_valid_path方法有啥作用吧。你可以去看源码具体了解

is_valid_path 检测传进去的url,是否能访问到资源。(说白了就是判断这个url是否存在我们定义的url映射中)

这样的话,上面这段代码就很简单了。首先判断APPEND_SLASH,如果为False的。那么这个方法should_redirect_with_slash直接返回False。如果APPEND_SLASH为True的话,再对请求的url进行判断,request.path_info它的值并不是一个完整的url,而是ip+端口后面的那一部分(也就是例子中的/test),判断它是否以斜线(/)结尾的,如果是的话,那么not request.path_info.endswith('/') 整体就为False,所以if判断后面的表达式就为False,最终返回了False。如果不是以斜线(/)结尾的话,那么if后面的表达式就为True,那么继续执行条件为真的代码块,这个代码块最终返回了一个表达式的结果,这个表达式类型是这样 bool and bool。也就是根据方法is_valid_pathd的返回值进行判断的,如果request.path_info(代码能分析到这里说明它不是以斜线结尾的),首先判断这个值能不能在我们写的路由关系映射中存不存在。存在的话,方法is_valid_path返回真,那么not True就为False,and左边的表达式为False,整体的表达式就为False,所以最终返回的就是False。如果request.path_info的值在路由关系映射中不存在,那么and左边的表达式为True,那就继续看and右边表达式的布尔值。and右边还是调用了方法is_valid_path,只不过传的参数是request.path_info + /,如果在路由映射中存在,那么最终返回True,如果不存在,那么就返回了False了。

should_redirect_with_slash方法分析完毕,继续看源码

# Check if a slash should be appended
if self.should_redirect_with_slash(request):
  path = self.get_full_path_with_slash(request)
else:
  path = request.get_full_path()

后面根据should_redirect_with_slash方法的返回值,做了不同的操作。不严格来说,不管True还是False,最终执行了requests.get_full_path这个方法,只不过传入的参数不同的,最终返回了一个完整的url请求地址。

继续往下看

# Return a redirect if necessary
if redirect_url or path != request.get_full_path():
  redirect_url += path
  return self.response_redirect_class(redirect_url)

如果if后面的表达式为True的话,最终稿返回了一个状态码为301的Httpresponse对象,这个对象里带这一个数据,这个数据就是在原url基础上加上斜线(/)的新url,前端接收到状态码为301的响应,则会继续请求响应中携带的新地址。为False的话,返回默认返回None。

django的中间件会根据每个中间件里的process_request方法或者process_response方法不同的返回值会执行相应的操作,具体操作不说了,不是这个知识点的内容。

那么中间件的process_request返回None的话,则会执行下一个中间件的process_request的方法。如果返回的是HttpResponse对象的话,则不会继续执行下一个中间件的process_request方法,则会执行process_response方法。具体从哪个中间件执行和django的版本有关系,反正是不会执行路由对应的视图代码的代码,会直接返回给前端HttpResoonse对象。

好了,关于APPEND_SLASH的知识总结完毕。APPEND_SLASH它默认为True,如果想要修改的话,需要在settings.py文件中定义这个常量,赋值为False,这样就可以覆盖原django中配置文件里对应的常量了。至于django内部怎么操作的,下次再总结吧

最后还是补个图吧,我把APPEND_SLASH设置为False,访问127.0.0.1:8000/test

python-django中的APPEND_SLASH实现方法

如果你设置了APPEND_SLASH为False,访问上面这个url,还是能访问到页面的话,清理下浏览器的缓存,就可以了

总结

以上所述是小编给大家介绍的python-django中的APPEND_SLASH实现,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
用Python制作在地图上模拟瘟疫扩散的Gif图
Mar 31 Python
举例讲解Python编程中对线程锁的使用
Jul 12 Python
Python中扩展包的安装方法详解
Jun 14 Python
django数据库migrate失败的解决方法解析
Feb 08 Python
解决python3 网络请求路径包含中文的问题
May 10 Python
python实现windows下文件备份脚本
May 27 Python
详解python里的命名规范
Jul 16 Python
浅谈Django的缓存机制
Aug 23 Python
Python XML转Json之XML2Dict的使用方法
Jan 15 Python
Python函数装饰器常见使用方法实例详解
Mar 30 Python
python面向对象实现名片管理系统文件版
Apr 26 Python
用Python爬取英雄联盟的皮肤详细示例
Dec 06 Python
Python2.7版os.path.isdir中文路径返回false的解决方法
Jun 21 #Python
pyqt5与matplotlib的完美结合实例
Jun 21 #Python
django框架防止XSS注入的方法分析
Jun 21 #Python
pyqt5中QThread在使用时出现重复emit的实例
Jun 21 #Python
python发送多人邮件没有展示收件人问题的解决方法
Jun 21 #Python
pyqt5让图片自适应QLabel大小上以及移除已显示的图片方法
Jun 21 #Python
django框架使用orm实现批量更新数据的方法
Jun 21 #Python
You might like
PHP PDO数据库操作预处理与注意事项
2019/03/16 PHP
js 提交和设置表单的值
2008/12/19 Javascript
firefo xml 读写实现js代码
2009/06/11 Javascript
Javascript面向对象编程(二) 构造函数的继承
2011/08/28 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
关于JavaScript对象的动态选择及遍历对象
2014/03/10 Javascript
jQuery使用prepend()方法在元素前添加内容用法实例
2015/03/26 Javascript
JavaScript 里的类数组对象
2015/04/08 Javascript
jQuery中的Deferred和promise 的区别
2016/04/03 Javascript
ES6中let、const的区别及变量的解构赋值操作方法实例分析
2019/10/15 Javascript
layui前端时间戳转化实例
2019/11/15 Javascript
[15:58]DOTA2国际邀请赛采访专栏:Tongfu.Sansheng&KingJ,DK.rOtk
2013/08/08 DOTA
收集的几个Python小技巧分享
2014/11/22 Python
python中Switch/Case实现的示例代码
2017/11/09 Python
对python 读取线的shp文件实例详解
2018/12/22 Python
Python搭建代理IP池实现存储IP的方法
2019/10/27 Python
基于Pycharm加载多个项目过程图解
2020/01/19 Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
2020/01/25 Python
django2.2 和 PyMySQL版本兼容问题
2020/02/17 Python
详解Ubuntu环境下部署Django+uwsgi+nginx总结
2020/04/02 Python
Keras使用ImageNet上预训练的模型方式
2020/05/23 Python
详解CSS3媒体查询响应式布局bootstrap 框架原理实战(推荐)
2020/11/16 HTML / CSS
使用phonegap检测网络状态的方法
2017/03/30 HTML / CSS
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
意大利会呼吸的鞋:Geox健乐士
2017/02/12 全球购物
美国优质马术服装购买网站:Breeches.com
2019/12/16 全球购物
牛津在线药房:Oxford Online Pharmacy
2020/11/16 全球购物
宿舍违规用电检讨书
2014/02/16 职场文书
老人祝寿主持词
2014/03/28 职场文书
公司担保书格式范文
2014/05/12 职场文书
敬老模范事迹
2014/05/21 职场文书
体育专业自荐书
2014/05/29 职场文书
Python批量将csv文件转化成xml文件的实例
2021/05/10 Python
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏
使用CSS实现百叶窗效果示例代码
2023/05/07 HTML / CSS