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, 前面上点开胃菜,现在才开始正餐了。
从上面可以看出来,path和re_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)
path和re_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的简单解析
本质上,URLPattern和Pattern都是两个被封装好的类,一个是路由整体对象,一个是用于路由匹配的匹配模式对象,在这里很好的体现了面向对象的封装性,在后续维护中,我们也能很好的进行修改维护,比如我们需要再添加一个匹配模型,我们可以另外单独定义一个Pattern类,传递给_path,这样就可以使用我们自己的模式匹配了。
5. 小结
当然,本篇文章只是简单介绍了path的底层源码,并没有分析具体的匹配过程,但下一篇文章会继更新相关的匹配过程。
明白了path的底层本质,对于后面我们分析具体的匹配机制,会更加轻松。
相关文章:

Django源码之路由的本质(上)——逐步剖析底层执行流程
目录 1. 前言 2. 路由定义 3. 路由定义整体源码分析 3.1 partial实现path函数调用 3.2 图解_path函数 3.3 最终 4.URLPattern和Pattern的简单解析 5. 小结 1. 前言 在学习Django框架的时候,我们大多时候都只会使用如何去开发项目,对其实现流程并…...

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

Native Instruments Kontakt 7 for Mac v7.9.0 专业音频采样
Native Instruments Kontakt 7是一款强大的软件采样器,它允许用户从各种来源采样音频并进行编辑和处理。它包含大量预设采样库,包括乐器、合成器、鼓组和声音效果等。此外,Kontakt 7还允许用户创建自己的采样库,以便根据自己的需要…...
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 框架
文章目录 一、介绍参考: 一、介绍 Forest是一个开源的Java HTTP客户端框架,专注于简化HTTP客户端的访问。它是一个高层的、极简的轻量级HTTP调用API框架,通过Java接口和注解的方式,将复杂的HTTP请求细节隐藏起来,使HT…...

Pandas Dataframe合并连接Join和merge 参数讲解
文章目录 函数与参数分析otheronhowlsuffix, rsuffix, suffixesleft_index, right_index 函数与参数分析 在pandas中主要有两个函数可以完成table之间的join Join的函数如下: DataFrame.join(other, onNone, how‘left’, lsuffix‘’, rsuffix‘’, sortFalse, v…...
ABC318 F - Octopus
解题思路 对于每个宝藏维护个区间,答案一定在这些区间中对于每个区间的端点由小到大排序对于每个点进行判断,若当前位置合法,则该点一定为一个右端点则该点到前一个端点之间均为合法点若前一个点不合法,则一定是某一个区间限制的…...
Docker实战教程 第3章 Dockerfile
4-2 通过dockerfile制作镜像 需求 制作一个具有ping ip ifconfig vim 这些命令工具的一个nginx镜像,通过dockerfile完成STEP1 : 写一个Dockerfile FROM nginx # 基于一个基础镜像 RUN lsstep2 docker build . -f 指定使用的dockerfile来生成镜像-t 指定镜像名…...
JSON在量化交易系统中的应用
JSON在量化交易系统中的应用场景 数据传输和存储:JSON可以将交易数据以结构化的方式进行编码,并将其转换为字符串进行传输和存储。这样可以方便地在不同的系统之间传递数据,并且可以保持数据的完整性和一致性。 API通信:量化交易…...

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

设置asp.net core WebApi函数请求参数可空的两种方式
以下面定义的asp.net core WebApi函数为例,客户端发送申请时,默认三个参数均为必填项,不填会报错,如下图所示: [HttpGet] public string GetSpecifyValue(string param1,string param2,string param3) {return $"…...
Vue.js组件精讲 开篇:Vue.js的精髓——组件
写在前面 Vue.js,无疑是当下最火热的前端框架 Almost,而 Vue.js 最精髓的,正是它的组件与组件化。写一个 Vue 工程,也就是在写一个个的组件。 业务场景是千变万化的,而不变的是 Vue.js 组件开发的核心思想和使用技巧…...

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

基于Python的微博旅游情感分析、微博舆论可视化系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...

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

0.17元的4位数码管驱动芯片AiP650,支持键盘,还是无锡国家集成电路设计中心某公司的
推荐原因:便宜的4位数码管驱动芯片 只要0.17元,香吗?X背景的哦。 2 线串口共阴极 8 段 4 位 LED 驱动控制/7*4 位键盘扫描专用电路 AIP650参考电路图 AIP650引脚定义...
【C++】编程规范之内存规则
在高质量编程中,内存管理是一个至关重要的方面。主要有以下原则: 内存分配后需要检查是否成功:内存分配可能会失败,特别是在内存紧张的情况下。因此,在分配内存后,应该检查分配是否成功。 int* ptr new …...

并发编程之线程池的应用以及一些小细节的详细解析
线程池在实际中的使用 实际开发中,最常用主要还是利用ThreadPoolExecutor自定义线程池,可以给出一些关键的参数来自定义。 在下面的代码中可以看到,该线程池的最大并行线程数是5,线程等候区(阻塞队列)是3,即…...

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

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

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...