Django中间件的源码解析流程(上)——中间件载入的前置

目录

1. ​前言​

2. 请求的入口

3. 中间件加载的入口

4. 源码中的闭包实现

5. 最后


1. 前言

哈喽,大家好,我是小K,今天咋们分享的内容是:在学会Django中间件之后, 我们继续深入底层源码。

在执行中间件时请求到来总是从前往后逐一匹配,但当响应返回时,执行的中间件顺序往往是反着执行的。

在Django中间件中,采用了多层闭包的形式,以来达到逐一执行中间件,本篇文章主要是从请求的入口开始,简单介绍一下前置。

如果还不会使用中间件的小伙伴可以跳转到这里:

Django之五种中间件定义类型

2. 请求的入口

在同步请求中,请求的入口其实就是 wsgi.py 文件, 不清楚的可以跳转这里,看第2点:

Django源码之路由匹配(下)——图解逐步分析底层源码

3. 中间件加载的入口

在请求到来时,最后返回的是一个WSGIHandler的一个对象

application = get_wsgi_application()def get_wsgi_application():django.setup(set_prefix=False)return WSGIHandler()class WSGIHandler(base.BaseHandler):request_class = WSGIRequestdef __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.load_middleware()

在加载对象时,肯定是少不了执行__init__的初始化方法的

self.load_middleware()   # 这其实就是加载中间件的方法

在执行load_middleware()函数时,首先是在自己的类中寻找,如果没有就去父类中寻找

显然,这里的代码是需要我们去父类BaseHandler类中寻找的


这里BaseHandler类和load_middleware的源码:

class BaseHandler:_view_middleware = None_template_response_middleware = None_exception_middleware = None_middleware_chain = Nonedef load_middleware(self, is_async=False):"""Populate middleware lists from settings.MIDDLEWARE.Must be called after the environment is fixed (see __call__ in subclasses)."""self._view_middleware = []self._template_response_middleware = []self._exception_middleware = []get_response = self._get_response_async if is_async else self._get_responsehandler = convert_exception_to_response(get_response)handler_is_async = is_asyncfor middleware_path in reversed(settings.MIDDLEWARE):middleware = import_string(middleware_path)middleware_can_sync = getattr(middleware, "sync_capable", True)middleware_can_async = getattr(middleware, "async_capable", False)if not middleware_can_sync and not middleware_can_async:raise RuntimeError("Middleware %s must have at least one of ""sync_capable/async_capable set to True." % middleware_path)elif not handler_is_async and middleware_can_sync:middleware_is_async = Falseelse:middleware_is_async = middleware_can_asynctry:# Adapt handler, if needed.adapted_handler = self.adapt_method_mode(middleware_is_async,handler,handler_is_async,debug=settings.DEBUG,name="middleware %s" % middleware_path,)mw_instance = middleware(adapted_handler)except MiddlewareNotUsed as exc:if settings.DEBUG:if str(exc):logger.debug("MiddlewareNotUsed(%r): %s", middleware_path, exc)else:logger.debug("MiddlewareNotUsed: %r", middleware_path)continueelse:handler = adapted_handlerif mw_instance is None:raise ImproperlyConfigured("Middleware factory %s returned None." % middleware_path)if hasattr(mw_instance, "process_view"):self._view_middleware.insert(0,self.adapt_method_mode(is_async, mw_instance.process_view),)if hasattr(mw_instance, "process_template_response"):self._template_response_middleware.append(self.adapt_method_mode(is_async, mw_instance.process_template_response),)if hasattr(mw_instance, "process_exception"):# The exception-handling stack is still always synchronous for# now, so adapt that way.self._exception_middleware.append(self.adapt_method_mode(False, mw_instance.process_exception),)handler = convert_exception_to_response(mw_instance)handler_is_async = middleware_is_async# Adapt the top of the stack, if needed.handler = self.adapt_method_mode(is_async, handler, handler_is_async)# We only assign to this when initialization is complete as it is used# as a flag for initialization being complete.self._middleware_chain = handler

 ok,我们现在着重来分析load_middleware的源码

4. 源码中的闭包实现

先来看看什么是闭包:

Python奇幻之旅(从入门到入狱基础篇)——附相关资料【中】-CSDN博客

这篇文章里面有一部分介绍了闭包和装饰器

现在来看具体的闭包实现函数:

def convert_exception_to_response(get_response):if iscoroutinefunction(get_response):@wraps(get_response)async def inner(request):try:response = await get_response(request)except Exception as exc:response = await sync_to_async(response_for_exception, thread_sensitive=False)(request, exc)return responsereturn innerelse:@wraps(get_response)def inner(request):try:response = get_response(request)except Exception as exc:response = response_for_exception(request, exc)return responsereturn inner

最后返回了一个inner函数, 而这个inner调用的是get_response()

最后都被封装进了handler里面

5. 最后

本文只是简单介绍了一下中间件加载的位置,下一篇文章将采用长篇的形式详细讲解中间件是如何通过闭包的形式载入的。今天就先到这里啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1472.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT研究论文提示词集合3-【数据收集】、【数据分析】和【解释与讨论】

点击下方▼▼▼▼链接直达AIPaperPass ! AIPaperPass - AI论文写作指导平台 目录 1.数据收集 2.数据分析 3.讨论与解释 4.书籍介绍 AIPaperPass智能论文写作平台 近期小编按照学术论文的流程,精心准备一套学术研究各个流程的提示词集合。总共14个步…

【IDEA】用idea导入eclipse的项目后,提示:The file was loaded in a wrong encoding ‘utf-8‘

前言 最近用IDEA导入一个exlipse项目后,窗口出现这个红色提示: 可以项目中的中文,包括注释都是乱码,要解决问题就跟我开始做吧。 一定要看仔细在操作! 一定要看仔细在操作! 一定要看仔细在操作&#xf…

rmallox勒索病毒威胁网络安全:如何避免数据被锁定

尊敬的读者: 随着信息技术的飞速发展,网络空间的安全问题日益凸显。近年来,一种名为.rmallox的勒索病毒频繁出没,给广大计算机用户带来了严重的困扰。本文将对该病毒进行深入剖析,并探讨相应的应对策略。在面对被勒索…

飞书API(5):查看多维表 28 种数据类型的数据结构

一、引入 前面我们用于测试的数据集其实都是比较常用的数据,比如说文本、数字、单选等,但飞书多维表并不仅仅只有这些数据,截止发文,飞书多维表应用上支持28种数据类型,在数据层面飞书官方只提供了23种数据类型&#…

微信小程序vue.js+uniapp服装商城销售管理系统nodejs-java

本技术是java平台的开源应用框架,其目的是简化Sping的初始搭建和开发过程。默认配置了很多框架的使用方式,自动加载Jar包,为了让用户尽可能快的跑起来spring应用程序。 SpinrgBoot的主要优点有: 1、为所有spring开发提供了一个更快…

AI 智能工具以及热门AI开源项目整理,包含国内中科院版GPT

AI 智能工具以及热门AI开源项目整理,包含国内中科院版GPT。 不用xx即可访问的镜像网站 https://chat1.yqcloud.top https://chat.bnu120.space https://chat.aidutu.cn https://hzdjs.cn/chatgpt https://chats.fenqubiao.com/zh 需要xx才能访问的网站 https://o…

「 网络安全常用术语解读 」什么是0day、1day、nday漏洞

1. 引言 漏洞攻击的时间窗口被称为漏洞窗口(window of vulnerability)。一般来说,漏洞窗口持续的时间越长,攻击者可以利用漏洞进行攻击的可能性就越大。 2. 0day 漏洞 0day 漏洞,又被称为"零日漏洞"&…

react之组件与JSX

第一章 - 描述用户界面 概述:React是一个用于构建用户界面(UI)的JavaScript库,用户界面由按钮,文本和图像等小单元内容构建而成。React帮助你把它们组合成可重用,可嵌套的组件。从web端网站到移动端应用&a…

【讲解下Spring Boot单元测试】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

【漏洞复现】WordPress_Wholesale_Market admin-ajax.php 任意文件读取漏洞

0x01 产品简介 WordPress Wholesale Market是一个WordPress主题,专门设计用于创建批发市场和在线商城网站。该主题提供了许多功能和设计元素,使您能够轻松地构建一个功能强大的批发市场平台,以满足批发商和零售商的需求。 0x02 漏洞概述 WordPress Wholesale Market存在任…

VL02N交货单清除字段:VLSTK(分配状态)

VL02N交货单清除字段:VLSTK(分配状态) 通过查找增强对应的BADI:LE_SHP_DELIVERY_PROC 修改方法:IF_EX_LE_SHP_DELIVERY_PROC~CHANGE_DELIVERY_HEADER,代码如下:

#QT获取ONENET云平台数据(草稿)

1.基本目标 (1)查询ONENT云平台的数据 (2)查询网络时间 (3)网络音乐拉取(作为背景音乐),音量可调 2.制作UI界面 (1)串口图标的制作方法 &…

天星金融(原小米金融)履行社会责任,提高社保政策知晓度

二十大报告指出“为民造福是立党为公、执政为民的本质要求“,人民幸福安康是推动高质量发展的最终目的。社会保障作为维护社会公平、增进人民福祉的基本制度,既是“安全网”也是“稳定器”,发挥着改善民生的重要作用。为进一步提升人民群众对…

如何解决DDoS攻击?群联科技做出回答。

DDoS攻击(分布式拒绝服务攻击)是一种恶意利用多台傀儡机协同发起大规模网络流量,旨在压垮目标系统或网络资源,使其无法正常服务的网络攻击手段。由于现代计算机和网络性能的提升,单点发起的DoS攻击已难以奏效&#xff…

独立样本t检验——python完整代码(直接运行就行)

#!/usr/bin/env python # -*- coding: utf-8 -*- # Author : 三十二画生JH # Contact : fjhstudent163.com # Software: PyCharm # Time : 2024/4/21 21:49 # Site : 网址 # File : t_test.py # Version : # ---功能描述 """ 对实验数据做独立样本&am…

博客网站/部署服务器---继上篇前端页面接入后端

目录 准备工作 创建用户类博客类与连接数据库 创建博客类 创建用户类 创建连接数据库工具类 实现对数据库数据博客的操作 实现对数据库用户的操作 创建数据库语句 登录页面 前端 后端 博客列表 前端 注销登录 写入数据 判断用户是否登录 替换页面用户昵称 后…

永恒之蓝上线CS

该文介绍了在内网环境下,利用永恒之蓝漏洞(EternalBlue)将攻击者控制台(CS)上线的方法。前提条件是目标机器可上网、无防火墙和杀毒软件,并且存在永恒之蓝漏洞。使用Erebus插件的eterblue功能,通…

xpath的使用以及原理-元素定位

# 查找文本框输入文本 driver.find_element(By.CLASS_NAME,"nav-search-input").send_keys("i_cecream查找到了") #查找到之后点击 driver.find_element(By.CLASS_NAME,"nav-search-btn").click()time.sleep(30)selenium4的解析。 client调用se…

2024团体程序设计天梯赛L1-103 整数的持续性

题目链接L1-103 整数的持续性 #include<iostream> #include<stdio.h> #include<algorithm> using namespace std; struct node{int x;int d; }p[2000]; bool cmp(node a, node b) {if (a.d b.d) return a.x < b.x;return a.d>b.d; } int cnt, cntt; v…

信号----硬件中断

硬件中断 键盘组合键是向进程发送信号&#xff0c;那么键盘数据是如何输入到内核中&#xff0c;然后变成信号的&#xff1f;这个信号又是由谁发送给进程的&#xff1f; 当键盘被按下&#xff0c;操作系统先知道用户用键盘输入了内容 那么操作系统是如何知道键盘上有内容了&…