当前位置: 首页 > news >正文

Django源码之路由的本质(上)——逐步剖析底层执行流程

目录

1. 前言

2. 路由定义

3. 路由定义整体源码分析

3.1 partial实现path函数调用

3.2 图解_path函数

3.3 最终

4.URLPattern和Pattern的简单解析

5. 小结


1. 前言

在学习Django框架的时候,我们大多时候都只会使用如何去开发项目,对其实现流程并不是很清楚明了。

这篇文章的目的就是带你先从Django最基础的路由层开始剖析底层源码,一步一步带你学会,Django路由是如何来进行实现的,它的底层又是基于什么来完成的。

2. 路由定义

若你只想看源码解析,请直接跳过当前点

Django的路由定义是在urls.py里面的,我们通过两种形式来定义路由:

  • 普通路由定义:path方法

urlpatterns = [path('test/', views.test),
]

第一个参数:路径名

第二个参数:执行的视图函数

  • 正则路由定义:re_path方法

from django.urls import path, re_pathfrom app01 import viewsurlpatterns = [re_path(r'login/(?P<name>\d{4})/', views.login),
]

第一个参数:路径+正则匹配

第二个参数:执行的视图函数

补充:

我在这里采用的有名分组,也就是将后面匹配到的参数传递给login函数,并且形参得跟路由定义的分组名一样

加上括号的原因:将匹配到的参数传递给视图函数,不加的话,就不会进行传递,只会进行匹配

  • 无名分组:没有名字的分组参数,将参数传递到函数,此时的形参可以任意名字:

urlpatterns = [re_path(r'login/(\d{4})/', views.login),
]

def login(request, vv):print(vv)return HttpResponse('code')

  • 有名分组:顾名思义,在进行正则匹配的时候,传递一个固定的参数名:

语法:?P<名字>

urlpatterns = [re_path(r'login/(?P<name>\d{4})/', views.login),
]

def login(request, name):print(name)return HttpResponse('code')

3. 路由定义整体源码分析

ok, 前面上点开胃菜,现在才开始正餐了。

从上面可以看出来,pathre_path已经帮我们都封装好了,我们只需要直接定义就好了,前面写匹配URL,后面写视图函数

那么此时,就会通过我们在网址栏输入的URL来进行相应视图函数的匹配

下面,我们来看path函数的内部实现

3.1 partial实现path函数调用

我们通过ctrl + 左键,点击path函数,可以进入到内部源码进行查看,如下:

path = partial(_path, Pattern=RoutePattern)

这里涉及到partial函数,大致说一下:

partial:可以实现在调用函数之前,固定一部分参数,并且返回一个新函数,

主要用于简化函数的调用,从而封装两个具有部分功能相同的函数,但部分不同的。提高了代码的可维护性和可读性。

用法

1. 参数一:原函数

2. 关键字参数:原函数的关键字参数,需要固定的一部分参数


可以从源码中,很好的体现这一点:

path = partial(_path, Pattern=RoutePattern)
re_path = partial(_path, Pattern=RegexPattern)

pathre_path的共同方法都是_path,都是采用相同的方式进行路由匹配的,但是不同的是他们匹配的方式是不一样的

path是普通的匹配,但是re_path是通过正则的形式来进行匹配的,所以我们通过提前固定好Pattern,来实现两个不同的匹配机制,这使得代码更有维护性,也更方便,只需要更改Pattern,就可以更换不同的匹配模式


当然,再写path的时候,我们所传递的参数,最终都会通过partial传递给_path

3.2 图解_path函数

我们先直接来看_path的整体

def _path(route, view, kwargs=None, name=None, Pattern=None):from django.views import Viewif kwargs is not None and not isinstance(kwargs, dict):raise TypeError(f"kwargs argument must be a dict, but got {kwargs.__class__.__name__}.")if isinstance(view, (list, tuple)):# For include(...) processing.pattern = Pattern(route, is_endpoint=False)urlconf_module, app_name, namespace = viewreturn URLResolver(pattern,urlconf_module,kwargs,app_name=app_name,namespace=namespace,)elif callable(view):pattern = Pattern(route, name=name, is_endpoint=True)return URLPattern(pattern, view, kwargs, name)elif isinstance(view, View):view_cls_name = view.__class__.__name__raise TypeError(f"view must be a callable, pass {view_cls_name}.as_view(), not "f"{view_cls_name}().")else:raise TypeError("view must be a callable or a list/tuple in the case of include().")

直接上图(通过代码 + 图解一步一步分析):

当然,里面有很多其实是不需要的,对于我们现在

我们逐步来进行分析并且删除:

  • 第一步

直接看黑色的圈起来的部分,这部分是判断传递进来的是否有kwargs这个额外参数,目前是用不上的,可以直接剔除

  • 第二步

这一部分可以看到,这里的isinstance是用于判断view是否是列表或者元组

回到开始,我们传递进来的path参数是一个视图函数 , 是一个函数,所以这部分也可以剔除

path('test/', views.test)
  • 第三步

callable 的作用是:判断当前是否为可执行的

函数,肯定是可执行的,所以会走这一层,那么下一层也不需要了

  • 最终

最终,我们获得目前的_path函数所需要的内容

def _path(route, view, kwargs=None, name=None, Pattern=None):from django.views import Viewpattern = Pattern(route, name=name, is_endpoint=True)return URLPattern(pattern, view, kwargs, name)

3.3 最终

可以看到哈,我们最终返回了一个

URLPattern(pattern, view, kwargs, name)

也就是URLPattern对象

URLPattern中,又封装了Pattern对象,而这个Pattern对象,其实就是最开始我们通过partial传递进来的匹配模式


所以,最终path函数就是这样的:

urlpatterns = [URLPattern(Pattern('test/', is_endpoint=True),views.test,)
]

本质上,就是一个URLPattern的对象

4.URLPattern和Pattern的简单解析

本质上,URLPatternPattern都是两个被封装好的类,一个是路由整体对象,一个是用于路由匹配的匹配模式对象,在这里很好的体现了面向对象的封装性,在后续维护中,我们也能很好的进行修改维护,比如我们需要再添加一个匹配模型,我们可以另外单独定义一个Pattern类,传递给_path,这样就可以使用我们自己的模式匹配了。

5. 小结

当然,本篇文章只是简单介绍了path的底层源码,并没有分析具体的匹配过程,但下一篇文章会继更新相关的匹配过程。

明白了path的底层本质,对于后面我们分析具体的匹配机制,会更加轻松。


 

相关文章:

Django源码之路由的本质(上)——逐步剖析底层执行流程

目录 1. 前言 2. 路由定义 3. 路由定义整体源码分析 3.1 partial实现path函数调用 3.2 图解_path函数 3.3 最终 4.URLPattern和Pattern的简单解析 5. 小结 1. 前言 在学习Django框架的时候&#xff0c;我们大多时候都只会使用如何去开发项目&#xff0c;对其实现流程并…...

基于深度学习的植物叶片病毒识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;本文深入研究了基于YOLOv8/v7/v6/v5的植物叶片病毒识别系统&#xff0c;核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;进行性能指标对比&#xff1b;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码&#xff0c;及基于Strea…...

Native Instruments Kontakt 7 for Mac v7.9.0 专业音频采样

Native Instruments Kontakt 7是一款强大的软件采样器&#xff0c;它允许用户从各种来源采样音频并进行编辑和处理。它包含大量预设采样库&#xff0c;包括乐器、合成器、鼓组和声音效果等。此外&#xff0c;Kontakt 7还允许用户创建自己的采样库&#xff0c;以便根据自己的需要…...

yolov8训练流程

训练代码 from ultralytics import YOLO# Load a model model YOLO(yolov8n.yaml) # build a new model from YAML model YOLO(yolov8n.pt) # load a pretrained model (recommended for training) model YOLO(yolov8n.yaml).load(yolov8n.pt) # build from YAML and tr…...

Java基础学习: Forest - 极简 HTTP 调用 API 框架

文章目录 一、介绍参考&#xff1a; 一、介绍 Forest是一个开源的Java HTTP客户端框架&#xff0c;专注于简化HTTP客户端的访问。它是一个高层的、极简的轻量级HTTP调用API框架&#xff0c;通过Java接口和注解的方式&#xff0c;将复杂的HTTP请求细节隐藏起来&#xff0c;使HT…...

Pandas Dataframe合并连接Join和merge 参数讲解

文章目录 函数与参数分析otheronhowlsuffix, rsuffix, suffixesleft_index, right_index 函数与参数分析 在pandas中主要有两个函数可以完成table之间的join Join的函数如下&#xff1a; DataFrame.join(other, onNone, how‘left’, lsuffix‘’, rsuffix‘’, sortFalse, v…...

ABC318 F - Octopus

解题思路 对于每个宝藏维护个区间&#xff0c;答案一定在这些区间中对于每个区间的端点由小到大排序对于每个点进行判断&#xff0c;若当前位置合法&#xff0c;则该点一定为一个右端点则该点到前一个端点之间均为合法点若前一个点不合法&#xff0c;则一定是某一个区间限制的…...

Docker实战教程 第3章 Dockerfile

4-2 通过dockerfile制作镜像 需求 制作一个具有ping ip ifconfig vim 这些命令工具的一个nginx镜像&#xff0c;通过dockerfile完成STEP1 : 写一个Dockerfile FROM nginx # 基于一个基础镜像 RUN lsstep2 docker build . -f 指定使用的dockerfile来生成镜像-t 指定镜像名…...

JSON在量化交易系统中的应用

JSON在量化交易系统中的应用场景 数据传输和存储&#xff1a;JSON可以将交易数据以结构化的方式进行编码&#xff0c;并将其转换为字符串进行传输和存储。这样可以方便地在不同的系统之间传递数据&#xff0c;并且可以保持数据的完整性和一致性。 API通信&#xff1a;量化交易…...

x-cmd-pkg | broot 是基于 Rust 开发的一个终端文件管理器

简介 broot 是基于 Rust 开发的一个终端文件管理器&#xff0c;它设计用于帮助用户在终端中更轻松地管理文件和目录&#xff0c;使用树状视图探索文件层次结构、操作文件、启动操作以及定义您自己的快捷方式。 同时它还集成了 ls, tree, find, grep, du, fzf 等工具的常用功能…...

设置asp.net core WebApi函数请求参数可空的两种方式

以下面定义的asp.net core WebApi函数为例&#xff0c;客户端发送申请时&#xff0c;默认三个参数均为必填项&#xff0c;不填会报错&#xff0c;如下图所示&#xff1a; [HttpGet] public string GetSpecifyValue(string param1,string param2,string param3) {return $"…...

Vue.js组件精讲 开篇:Vue.js的精髓——组件

写在前面 Vue.js&#xff0c;无疑是当下最火热的前端框架 Almost&#xff0c;而 Vue.js 最精髓的&#xff0c;正是它的组件与组件化。写一个 Vue 工程&#xff0c;也就是在写一个个的组件。 业务场景是千变万化的&#xff0c;而不变的是 Vue.js 组件开发的核心思想和使用技巧…...

R语言中的常用数据结构

目录 R对象的基本类型 R对象的属性 R的数据结构 向量 矩阵 数组 列表 因子 缺失值NA 数据框 R的数据结构总结 R语言可以进行探索性数据分析&#xff0c;统计推断&#xff0c;回归分析&#xff0c;机器学习&#xff0c;数据产品开发 R对象的基本类型 R语言对象有五…...

基于Python的微博旅游情感分析、微博舆论可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

机器学习的模型校准

背景知识 之前一直没了解过模型校准是什么东西&#xff0c;最近上班业务需要看了一下&#xff1a; 模型校准是指对分类模型进行修正以提高其概率预测的准确性。在分类模型中&#xff0c;预测结果通常以类别标签形式呈现&#xff08;例如&#xff0c;0或1&#xff09;&#xf…...

0.17元的4位数码管驱动芯片AiP650,支持键盘,还是无锡国家集成电路设计中心某公司的

推荐原因&#xff1a;便宜的4位数码管驱动芯片 只要0.17元&#xff0c;香吗&#xff1f;X背景的哦。 2 线串口共阴极 8 段 4 位 LED 驱动控制/7*4 位键盘扫描专用电路 AIP650参考电路图 AIP650引脚定义...

【C++】编程规范之内存规则

在高质量编程中&#xff0c;内存管理是一个至关重要的方面。主要有以下原则&#xff1a; 内存分配后需要检查是否成功&#xff1a;内存分配可能会失败&#xff0c;特别是在内存紧张的情况下。因此&#xff0c;在分配内存后&#xff0c;应该检查分配是否成功。 int* ptr new …...

并发编程之线程池的应用以及一些小细节的详细解析

线程池在实际中的使用 实际开发中&#xff0c;最常用主要还是利用ThreadPoolExecutor自定义线程池&#xff0c;可以给出一些关键的参数来自定义。 在下面的代码中可以看到&#xff0c;该线程池的最大并行线程数是5&#xff0c;线程等候区&#xff08;阻塞队列)是3&#xff0c;即…...

基于JSP的农产品供销服务系统

背景 互联网的迅猛扩张彻底革新了全球各类组织的运营模式。自20世纪90年代起&#xff0c;中国的政府机关和各类企业便开始探索利用网络系统来处理管理事务。然而&#xff0c;早期的网络覆盖范围有限、用户接受度不高、互联网相关法律法规不完善以及技术开发不够成熟等因素&…...

redis之主从复制、哨兵模式

一 redis群集有三种模式 主从复制&#xff1a; 主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。 主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障恢复。 缺陷&#xff1a; 故障恢复无法自动化&…...

【随笔】Git 基础篇 -- 分支与合并 git rebase(十)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…...

图像识别技术在体育领域的应用

图像识别技术在体育领域的应用是一个充满创新和挑战的研究方向。随着计算机视觉和人工智能技术的快速发展&#xff0c;图像识别技术已经在体育领域展现出广泛的应用潜力和实际价值。以下是一些图像识别技术在体育领域的具体应用&#xff1a; 运动员表现分析&#xff1a; 图像识…...

【项目新功能开发篇】开发编码

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…...

软件设计原则:开闭原则

定义 开闭原则&#xff08;Open-Closed Principle, OCP&#xff09;是面向对象设计的基本原则之一&#xff0c;由 Bertrand Meyer 提出。它指出软件实体&#xff08;类、模块、函数等&#xff09;应该对扩展开放&#xff0c;对修改封闭。这意味着软件应该设计成在不修改现有代…...

Python如何下载视频

大家好&#xff0c;今天我将为大家介绍如何使用Python来下载视频。Python作为一门强大的编程语言&#xff0c;不仅可以用于数据分析、机器学习等领域&#xff0c;还能用于网络爬虫和视频下载等任务。下面我将详细介绍如何使用Python来下载视频。 首先&#xff0c;我们需要明确…...

使用虚拟引擎为AR体验提供动力

Powering AR Experiences with Unreal Engine ​​​​​​​ 目录 1. 虚拟引擎概述 2. 虚拟引擎如何为AR体验提供动力 3. 虚拟引擎中AR体验的组成部分是什么&#xff1f; 4. 使用虚拟引擎创建AR体验 5. 虚拟引擎中AR的优化提示 6. 将互动性融入AR与虚拟引擎 7. 在AR中…...

Kafka入门到实战-第五弹

Kafka入门到实战 Kafka常见操作官网地址Kafka概述Kafka的基础操作更新计划 Kafka常见操作 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://kafka.apache.org/Kafka概述 Apache Kafka 是一个开源的分布式事件流平台&…...

Ideal Holidays

题目链接 AtCoder Beginner Contest 347 C - Ideal Holidays 思路&#xff1a; 一周有 A B AB AB 天&#xff0c;前 A A A 天放假&#xff0c;问能不能把所有工作放进节假日里。 先看简单的&#xff0c;两个。其实我们并不是很在乎它们中间隔了多少天&#xff0c;我们只…...

Raven:一款功能强大的CICD安全分析工具

关于Raven Raven是一款功能强大的CI/CD安全分析工具&#xff0c;该工具旨在帮助广大研究人员对GitHub Actions CI工作流执行大规模安全扫描&#xff0c;并将发现的数据解析并存储到Neo4j数据库中。 Raven&#xff0c;全称为Risk Analysis and Vulnerability Enumeration for C…...

【苹果MAC】苹果电脑 LOGI罗技鼠标设置左右切换全屏页面快捷键

首先键盘设置->键盘快捷键 调度中心 设置 f1 f2 为移动一个空间&#xff08;就可以快捷移动了&#xff09; 想要鼠标直接控制&#xff0c;就需要下载官方驱动&#xff0c;来设置按键快捷键&#xff0c;触发 F1 F2 安装 LOGI OPTIONS Logi Options 是一款功能强大且便于使用…...

素材中国免费素材网官网/百度seo和谷歌seo有什么区别

文章目录1. Spring Boot1.1 什么是Spring Boot&#xff1f;1.2 SpringBoot 官方的一些解释2. 微服务架构2.1 单体应用架构2.2 微服务架构2.3 分布式要解决的问题3. 搭建第一个SpringBoot程序3.1 在官方下载一个SpringBoot程序3.2 在IDEA中&#xff0c;创建SpringBoot程序(推荐)…...

wordpress微擎/日照seo公司

在 ECMAScript 规范中&#xff0c;共定义了 7 种数据类型&#xff0c;分为 基本类型 和 引用类型 两大类&#xff0c;如下所示&#xff1a; 基本类型&#xff1a;String、Number、Boolean、Symbol、Undefined、Null 引用类型&#xff1a;Object 基本类型也称为简单类型&#x…...

保温管有哪些网站做/google chrome官网下载

Dan Griffin本文讨论: 新的凭据提供程序体系结构 为什么弃用了基于 GINA 的身份验证 多因素 (Multi-factor) 身份验证 开发和调试凭据提供程序 本文使用了以下技术: Windows Vista、C目录 新旧两种体系结构的比较 混合凭据提供程序 要求 设计 混合凭据提供程序 混合方式的实现…...

合肥网络公司 网站建设/成功的软文推广

浅谈C语言中函数形参为地址类型定义形式和类型自动转换浅谈C语言中函数形参为地址类型定义形式和类型自动转换摘要&#xff1a;当函数参数为地址类型时&#xff0c;可以有多种定义形式&#xff0c;因而读者易产生迷惑&#xff0c;通过对各种实例的分析和证明&#xff0c;介绍了…...

视频网站建设需要多少钱/黄页网络的推广网站有哪些

文章目录引言一、基本概念1.读写分离(1) 什么是读写分离(2) 为什么要读写分离(3) 什么时候要读写分离(4) 主从复制与读写分离2. MySQL 主从复制(1) mysql 支持的复制类型(2) 主从复制的工作过程(3) mysql 主从复制高延迟的原因(4) mysql 主从复制高延迟的解决办法3. 常见的 MyS…...

丹阳网站推广/免费建站模板

题目 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode-cn.com/problems/maximum-length-of-subarray-with-positive-product 著作权归领扣网络所有。商业转载请联系官方授权&#xff0c;非商业转载请注明出处。 给你一个整数数组 num…...