首页 > 其他分享 >06-路由-组件详解

06-路由-组件详解

时间:2023-01-21 17:11:07浏览次数:70  
标签:06 URLPattern URLResolver 对象 RegexPattern 详解 path 路由

上一篇博客中已经展示了部分路由解析的源码,但是比较大概,不够清晰,只能提供调试的思路。这一篇博客将会抽出路由的每一个组件。详细阐述路由如何解析的。
前面不会连贯起每一个类,因为本篇博客将会是从内向外

URLPattern

URLPattern 最简单,我们先来说说这个,注意,截图中的箭头指向的参数的关系,某一个参数或者指向了一个类,或者指向了另一方法中的参数,表示他们是同一个东西,细细看一下,是可以看懂的。

【1】re_path 函数其实调用的是 _path 函数,_path 通过控制最后一个参数,包装为 re_path 或者 path。而 _path 尝试返回一个 URLPattern 对象或者 URLResolver 对象,其中 URLResolver 对象最后也会解析到一个个的 URLPattern 对象,本次以 URLPattern 作为讲解。
【2】尝试构造一个 Pattern 对象,这个 Pattern 其实是 RegexPattern 对象,因为是传参进来的,所以可以看做被重命名了。构造参数 route 正是 r'^$'
【3】尝试构造一个 URLPattern 对象,他需要的第一参数正是第二步构造的 RegexPattern 对象,第二个参数是【1】中的视图函数,这里形成了一个绑定关系,
【4】其实调用了【5】所在的 match 方法
【5】看着像是正则调用,但是 RegexPattern.regex 怎么会有 search 方法或者 fullmatch 方法,这两个是正则对象,RegexPattern.regex 是一个 LocaleRegexDescriptor 对象。注意:LocaleRegexDescriptor 对象是作为 RegexPattern 的类属性,且 LocaleRegexDescriptor 类中写了一个 __get__,所以 LocaleRegexDescriptor 其实是一个描述器,描述器的具体用法,请看 这篇博客self.regex 触发了【6】
【6】instance 指向了当前的 RegexPattern 对象,而 self.attr 则在 LocaleRegexDescriptor 作为类属性初始化的时候就传进去了,当前为 _regex。于是这里就是尝试从当前的 RegexPattern 对象中获取 _regex 这个对象,有吗?请看 RegexPattern 的初始化方法。此时 regex 的值为 r'^$' ,于是触发了【7】的执行
【7】尝试调用 RegexPattern._compile 方法,并将结果添加给当前的 RegexPattern 实例作为属性,这样做的好处是实现了懒加载,非必要不生成对象。

RegexPattern._compile

这里返回了一个正则对象,所以正则对象就是这么来的。现在 self.regex 就有了 fullmatch 方法和 search 方法。
所以 RegexPattern.match 方法尝试获取一个 match 对象,也就是正则对象对路由字符串的解析结果,在 RegexPattern.match 的后半段,将正则对象的解析结果提取出来作为视图函数的参数。

URLPattern 有两个重要的参数
【1】pattern 用来校验url和当前的正在比较的路由是否匹配,并且提取请求参数
【2】当前路由绑定的视图函数

URLResolver

URLResolver 一般用来接收一个 include 函数的返回值。

include 的返回值是一个三元组,因此可以看做 URLResolver 存储的就是一个列表,里面的每一个元素可以是 URLResolver[存在子应用],也可以是 URLPattern。在这里我们假设列表中每一个元素都是 URLPattern 的实例。对于列表中存在 URLResolver 的实例的情况,可以类推。

URLResolver 跟 URLPattern 很类似,他也需要接收一个正则表达式作为 pattern, 通常是当前应用的开头,用于从上一级路由跳到当前路由。URLResolver 还存放了下一层路由,也就是子应用中的列表。这个 include 已经完成了导入操作。所以这里存放的其实就是个列表。

【1】尝试调用 RegexPattern.match 方法
【2】同上半部讲的一样,通过描述器加反射构造了一个正则对象,于是可以调用 fullmatch 方法或者 search 方法。
【3】这里的代码比较重点,将当前的正则字符串从 url 中去掉了,方便拿到下一级路由去匹配。需要注意的是 new_path URLPattern 的resolve 方法中被丢弃了,因为如果当前是 URLPattern 调用了 resolve 方法,说明将要提取视图函数了。同时从 url 中提取查询参数
【4】对 RegexPattern.match 的返回值进行解包。
【5】在 for 循环内,对每一个列表的元素尝试匹配请求,这时传入的是 new_path,也就是去掉了当前的 URLResolver 的匹配字符串。到了【5】这里就已经跟上半篇博客一样了。

需要注意的是:在 URLResolver.resolve 的循环内部,如果匹配到了路由就不会向下走了,他不会检查所有能匹配上的路由。如果他没有匹配上的话,他会记录当前已经匹配过得路由,用于返回给前端,是否路由输入错了。

URLResolver 和 URLPattern 配合使用,URLPattern 用于最终匹配到路由,并且提取出视图函数,URLResolver 用于跳到下一层路由或者扫描当前所有的元素。

标签:06,URLPattern,URLResolver,对象,RegexPattern,详解,path,路由
From: https://www.cnblogs.com/yaowy001/p/17062980.html

相关文章

  • 【Javaweb】Servlet五 | HTTP协议【详解】
    什么是HTTP协议什么是协议?协议是指双方或多方相互约定好,大家都需要遵守的规则,叫协议。所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫做HTTP协......
  • 从路由器真机提取固件包(一)
    前言看IOT也有一段时间了,但是一直都是从官网获取固件包,没有尝试过从真机里提取固件。在看了一些师傅的文章后决定尝试一下从真机中提取固件。正好手里也有几个路由器,于是......
  • Target EDI对接详解 – EDI业务测试及上线
    Target塔吉特是美国仅次于Walmart沃尔玛的第二大巨型折扣零售百货集团,在2020财年实现零售收入同比增长19.8%,赶超了CVS和Tesco,并在2020财年的销售额增长超过150......
  • 06给数组增加一个维度
    importnumpyasnparr=np.arange(5)print(arr)print(arr.shape)#method1print(arr[np.newaxis,:])print(arr[np.newaxis,:].shape)print(arr[:,np.newaxis])......
  • 05-路由-请求之时
    这一篇博客我们尝试使用调试,看看整个请求是怎么触发的,也就是从Django接收到请求到调用具体的视图的流程,我们不尝试探讨整条链路,那样太多了。他们将会在后续的章节中讲解。......
  • DBNet源码详解
    参考项目:https://github.com/WenmuZhou/DBNet.pytorch标签制作制作thresholdmap标签make_border_map.py程序入口if__name__=='__main__'if__name__=='__main......
  • Openwrt路由器搭建网站教程
      最近都在折腾这个,多方借鉴了一下,萌新一枚,分享一下过程,不足之处,还请大佬指点指点本文主要内容:1.安装Entware2.安装ONMP3.安装可道云网站程序准备材料:1......
  • Spring AOP中@Pointcut切入点表达式详解
    目录一、瞅一眼标准的AspectJAop的pointcut的表达式二、SpringAop的十一种AOP表达式三、演示使用1、execution:2、within:3、this:4、target:5、args:6、@target:7、......
  • day06-Spring管理Bean-IOC-04
    Spring管理Bean-IOC-043.基于注解配置bean3.1基本使用3.1.1说明基本说明:基于注解的方式配置bean,主要是项目开发中的组件,比如Controller,Service和Dao组件的注解形式有:......
  • KMP 详解
    简介KMP这个名字的由来:它是三个人:D.E·Knuth、J.H·Morris和V.R·Pratt同时发现的。KMP是一种字符串单模匹配算法,复杂度\(\operatorname{O(n+k)}\)。其中......