当前位置: 首页 > 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; 故障恢复无法自动化&…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...