Django中间件Middleware

深入理解Django的中间件middleware 主要给大家介绍了关于Django中的中间件middleware的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。 立即下载

django中间件

一、中间件详细分析

1.django配置文件settings.py

# settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
         ...  ... 
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
     # 把自己定义的middlerware.py中间件添加进来
    'pay_gateway.process_handle_middleware.ProcessHandleMiddleware'
]

2.自定义中间件middleware.py

# middleware.py
from django.utils.deprecation import MiddlewareMixin

class ProcessHandleMiddleware(MiddlewareMixin):
    """
    以下几个函数的顺序,刚好也是中间件的执行顺序,
    按需在适当的位置做操作
    """
    def __init__(self, *args, **kwargs):
        """
        如果需要额外初始化数据则定义
        """
        super(ProcessHandleMiddleware, self).__init__(*args, **kwargs)
        self.start_time = time.time()

    def process_request(self, request):
        """request请求一进来的预处理函数。
            - 在Django接收到request之后,未解析URL到对应视图函数之前。Django向它传入相应的Request对象,以便在方法中修改。
            - 若返回None,Django将继续处理这个request,执行后续的中间件, 然后调用相应的 view。
            - 若返回HttpResponse对象,Django将不再执行任何除了process_response(返回浏览器的最后一层干预)以外其它的中间件
              以及相应的view,Django将立即返回该HttpResponse
            - 这里如果报错,后边所有的中间件都就不执行了,直接返回(由内部对error处理,报500)
        """
        print("request arrive ...")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        """进view前的预处理函数
            - 在Django执行完request预处理,路由解析完毕,确定待执行的view函数(即callback函数)之后,但在view实际执行之前
        :param request: HttpRequest 对象
        :param callback: Django将调用的处理request的python函数. 这是实际的函数对象本身, 而不是字符串表述的函数名
        :param callback_args: 将传入view的位置参数列表,但不包括request参数(它通常是传入view的第一个参数)
        :param callback_kwargs: 将传入view的关键字参数字典
        :return:
            - 如果返回None, Django将继续处理这个request ,执行后续的中间件, 然后调用相应的view
            - 如果返回HttpResponse对象,Django将不再执行任何其它的中间件(不论种类)以及相应的view,Django会立即返回
            - 这里如果报错,后边所有的中间件都就不执行了,直接返回(由内部对error处理,报500)
        """
        print("before view")

    def process_template_response(self):
        """template模板渲染函数
            - 默认不执行,只有在view函数返回的结果对象中有render方法才会执行
            - 若返回的话,会把对象内执行render方法后的返回值返回给用户(不返回view返回的对象,而是其对象内render方法的返回值)
        """
        print("template response ")

    def process_exception(self, request, exception):
        """只有view函数处理抛出的错误才能接到,其他的错误,这里并不能捕获
            - 可做异常通知,错误日志搜集,或尝试从错误中自动恢复
            - 若返回None,Django将用框架内置的异常处理机制继续处理相应request
            - 若返回HttpResponse对象,Django将使用该response对象,而短路框架内置的异常处理机制,直接返回(其他异常处理便不再执行)
        """
        print("process exception")

    def process_response(self, request, response):
        """在view函数返回response对象之后,马上要返回给用户之前,对其进行二次处理
            - 如:用gzip压缩返回数据
            - 这里必须要返回HttpResponse对象!!!   (可以是view返回的,也可是全新的,也可是处理过的,但必须是HttpResponse对象)
        """
        print("process response ... ... ")
        return response

3.注意事项:

  • process_view在settings.py中的MIDDLEWARE中,后放的先执行,其他过程是先放的先执行。

  • process_response一定要有reurn否则会报错,自定义的中间件response方法没有return,会交给下一个中间件,导致http请求中断了。

  • process_view(self, request, callback,callback_args, callback_kwargs)方法介绍:

    • (1)执行完所有中间件的request方法
    • (2)url匹配成功
    • (3)拿到视图函数的名称、参数(注意不执行),再执行process_view()方法(传递view函数以及相关参数,但是还是不执行)
    • (4)最后去执行视图函数

4.看图分析

二、简化版,以及参数分析

class LoggerMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        print("start request".center(50, "*"))
        print(request)   # <WSGIRequest: GET '/apis/author/?limit=1'>
        print(type(request))   # <class 'django.core.handlers.wsgi.WSGIRequest'>
        print(dir(request))
        # req_method = request.method
        # if req_method == 'GET':
        #     req_data = request.

        print(request.method)  # yes
        print(request.content_type)
        print(request.META)   # meta数据
        print(request.META['REMOTE_ADDR'])   # 127.0.0.1
        print(type(request.META['REMOTE_ADDR']))   # <class 'str'>
        # print(request.META['HTTP_X_REAL_IP'])  # 这个可能有,可能没有。要和REMOTE_ADDR组合起来使用
        print(request.content_params)  # {}
        print(request.encoding)
        print(request.body)   # 二进制 b'{\n  "birthday": "2019-07-04",\n  "telephone": "string",\n  "addr": "\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a"\n}'
        print(str(request.body, encoding="utf-8"))  # {"birthday": "2019-07-05", "telephone": "string", "addr": "string"}
        print(request.get_full_path())   # /apis/author/?limit=1   请求从根路径开始的所有路径
        print(request.get_host())      #  127.0.0.1:8000    服务器主机
        print(request.scheme)   # http
        print(request.GET)   # <QueryDict: {'limit': ['1']}>
        print(type(request.GET))   # <class 'django.http.request.QueryDict'>
        print(dir(request.GET))
        print(request.GET.dict())   # {'limit': '1'}  get方法时用这个参数接查询字符串
        print(request.POST)  # <QueryDict: {}>
        print(type(request.POST))  # <class 'django.http.request.QueryDict'>
        print(dir(request.POST))
        print(request.POST.dict())
        print(request.POST.items())
        print(request.POST.lists())
        # print({k:v for k, v in request.POST.items()})
        for k, v in request.POST.items():
            print("%s=%s"%(k,v))
        print(request.POST.keys())  # dict_keys([])

        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        print("get response data".center(50, ">"))
        print(type(response))   # <class 'rest_framework.response.Response'> 这个用的是rest_framework的Response进行的数据返回
        print(dir(response))
        print(response)   # <Response status_code=200, "application/json">
        print(response.status_code)  # 200
        # print(response.status_text)  # OK  JsonResponse没有这个属性
        # print(response.data)     # resp  data 就记录这个就行, JsonResponse没有这个属性
        print(response.content)   # 二进制的resp返回数据
        # print(response.context_data)  # None,  JsonResponse没有这个属性
        print(response.items())  # JsonResponse有,   dict_values([('Content-Type', 'application/json'), ('Allow', 'GET, POST, PUT, DELETE, HEAD, OPTIONS')])
        print(response.readable())  # JsonResponse有,   False
        print(response.serialize())  # b'Content-Type: application/json\r\nAllow: GET, POST, PUT, DELETE, HEAD, OPTIONS\r\n\r\n{"name": "lili"}'

        # Code to be executed for each request/response after
        # the view is called.

        return response

三、应用实例

# 添加了每次请求的详细信息的日志记录
# 添加了返回值的二次处理封装成统一的格式
# 统一处理了自定义错误的处理,以及返回格式的统一

from django.http.response import JsonResponse

class ServerException(Exception):
    def __init__(self, reason, *args):
        self.reason = reason
        self.code = error_dict[self.reason]['code']
        self.data = None
        self.msg = error_dict[self.reason]["msg"] % args

    def to_response(self):
        return JsonResponse({
            "code": self.code,
            "reason": self.reason,
            "data": self.data,
            "msg": self.msg
        })


class ProcessHandleMiddleware(MiddlewareMixin):

    def __init__(self, *args, **kwargs):
        super(ProcessHandleMiddleware, self).__init__(*args, **kwargs)
        self.start_time = time.time()

    def process_request(self, request):
        """
        - 这里不能调用Response进行数据返回!
        - Response或SimpleTemplateResponse等实际返回的是Response().render(),
          而如果想进行渲染,那么在实例化时需要指定各种渲染类。
          但Response中是没有渲染类的默认值,而在View中会取默认值给Response,
          因而经过view的可以返回,自己在此位置直接调用并返回是不可以。
        - HTTPResponse和JSONResponse是直接拼凑二进制数据的响应,不存在渲染操作,所以可以直接返回
        """

    def process_exception(self, request, exception):
        capture_exception()
        if isinstance(exception, ServerException):
            return exception.to_response()

    def process_response(self, request, response):
        """
        1.如果想实现参数封装,这里只能使用rest_framework.response.Response !!!
        2.只针对接口函数的返回值做封装+日志记录
        """
        if str(request.path).startswith("/open-api"):
            # 参数封装
            if hasattr(response, 'data') and isinstance(response, Response):
                data = response.data
                response.data = {
                    'code': 0,
                    'data': data,
                    'reason': "SUCCESS",
                    'msg': '成功'
                }
                # 这里因为已经是实例了,渲染类相关的都已经存在于对象中了,所以这里可以这么操作
                # 因返回时已经render过response,要想让这里的修改有效,需要手动在render一次
                response._is_rendered = False
                response.render()

            # 记录日志
            req_data = ""
            if request.method == 'GET':
                req_data = request.GET.dict()
            elif request.method == 'POST':
                req_data = str(request.body, encoding='utf-8')

            resp = ""
            if hasattr(response, "content"):
                resp = response.content.decode("utf-8")
            end_time = time.time()
            log_info = "<[REQUEST MESSAGE]>: [req_path]: %s, [mehtod]: %s, [cost_time]: %.2f s, [status]: %s, [req_data]: %s, [resp_data]: %s" % (
                request.path,
                request.method,
                end_time - self.start_time,
                response.status_code,
                req_data,
                resp
            )
            logging.info(log_info)
        return response

别再只用线性回归了!用sklearn的核岭回归搞定非线性数据(附RBF核调参实战) 本文详细介绍了如何使用sklearn的核岭回归处理非线性数据,特别是RBF核的应用与调参实战。通过网格搜索找到最佳参数组合,核岭回归能有效捕捉数据中的复杂波动,显著提升模型性能。适合需要解决非线性问题的数据科学家和机器学习工程师。 阅读详情

相关推荐

mysql9.0windows安装

将这里的位置修改为你刚刚创建并复制data目录的地址即可,win11的系统使用vscode修改之后,会让你确认开启更高权限以进行保存,比较方便,window10不需要确认,修改后可以直接保存。:在修改之前,最好将下图文件进行备份,将原始的文件保存好一份,以防更改了配置之后,导致mysql服务报错,无法启动,备份好的话直接将有问题的配置文件给替换就可以,无需重新安装一次mySql。双击下载的msi文件进行安装。安装有问题的,可以直接进行卸载,新本的mySql会将注册表中的数据自动进行清除,还是很方便的。

m0_74824123的博客 6448

django middleware 中间件原理概念,源码解读分析

django middleware 中间件原理概念,源码解读分析

yuencczzy的博客 391

Git GUI学习教程

学习宗旨:快速应用,不易忘记 很遗憾,申请Git的专栏未审批,那我就不再写专栏了,把最近的学习心得写一下,我也是在学习中进行,有任何问题直接留言,回复交流,我还采用思路+实践模式快速过。 目录 1、Git是什么 2、远程仓库 1)GitHub: 2)Gitee(码云): 3、安装Git(Windows) 1)下载 ...

Alexantao 的专栏 7254

Django(7)|middleware中间件

在django中的请求和响应中,可以利用中间件干预视图的请求和响应。1.在项目主目录中创建一个middlewaretest.py的文件。2.在middlewaretest.py中重写中间件函数。①middlewaretest.py重写方法。3.在settings.py中配置中间件。中间件是一个面向对象的类,有五个方法。②将配置文件修改为所有人均可访问。③命令行输入命令运行。

不愿意透露姓名的网友 1860

蓝牙Channel Sounding为真正的距离感知赋能

1:工作原理蓝牙™信道探测使用两种经过验证的测距方法——PBR(PBR)和RTT(RTT),实现蓝牙设备之间的安全精密测距。

weixin_43720159的博客 807

QFN封装芯片手工焊接实战:从焊盘处理到拖焊技巧

本文详细介绍了QFN封装芯片手工焊接的全过程,从焊盘处理到拖焊技巧,再到常见问题的现场修复方法。通过实战经验分享,帮助工程师和DIY爱好者掌握0.5mm小间距QFN芯片的焊接技术,提升焊接成功率和质量。重点讲解了垂直与平行拖焊手法的对比应用,以及焊后清理与质量检验的关键步骤。

weixin_42652674的博客 532

Django学习笔记九:Django中间件Middleware

Django中间件(Middleware)是一段在Django的请求/响应处理过程中,可以介入并改变请求或响应的代码。中间件是Django框架中一个非常强大的功能,它允许你在Django的视图函数之前或之后执行自定义代码。Django中间件的工作原理是,中间件以一个有序列表的形式存在,Django会按照这个列表的顺序调用中间件。

软件行业技术文化交流。 1407

S7-200 SMART Modbus RTU从站配置与调试实战指南

本文提供了一份详细的S7-200 SMART PLC配置为Modbus RTU从站的实战指南。内容涵盖从硬件基础、软件准备、指令库调用、核心编程到地址映射与调试排错的完整流程。重点解析了MBUS_INIT与MBUS_SLAVE指令的关键参数配置,并深入探讨了Modbus地址与PLC内部V存储区的对应关系,帮助工程师快速打通通讯链路,实现与上位机、触摸屏等主站设备的稳定数据交互。

potato的博客 755

laravel mews/captcha session 失效

因为我是api接口,同时还是两个顶级域名。所以session问题无法解决,我就将他们存储到redis中去了,在文件/vendor/mews/captcha/src/Captcha.php中改动。 方法create中加入 public function create(string $config = 'default', bool $api = false) { $this->backgrounds = $this->files->files(__DIR__ .

weixin_39577247的博客 625

基于NAS的OpenClaw部署方案:家庭服务器架构设计

本文提出了一种基于NAS的家庭服务器架构方案,用于部署OpenClaw AI系统。文章分析了NAS作为部署平台的六大优势:集中化数据管理、大容量存储、多用户并发访问、7×24小时稳定运行、低功耗设计以及丰富的扩展能力。针对不同用户需求,详细对比了主流NAS型号(如Synology DS923+、QNAP TS-870等)和DIY方案的硬件配置,并给出了最低/推荐配置标准。在部署方案部分,重点介绍了Synology DSM和TrueNAS两种系统的初始化步骤,以及通过Docker容器安装Python、Redi

博客 2509

【雕爷学编程】Arduino动手做(75)---TTL转RS-485模块之二线制可以实现真正的多点双向通信

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验七十五:TTL转RS-485模块 MAX485 RS485模块 MAX485 是一个8.

雕爷学编程 1万+

Backend - Django Middleware 中间件

知识量决定了未来能走多远

是萝卜干呀的博客 1302

基于STM32设计的智能水产养殖系统(2025)_359

本设计提出并实现了一种基于STM32F103RCT6微控制器的智能水产养殖控制系统,针对传统水产养殖中人工依赖高、环境参数监测滞后、控制手段单一等问题,集成了TDS水质检测、水温检测、水位监测、自动喂食、自动充氧、换水控制与加热保温等功能。系统采用ESP8266模块实现WIFI联网,通过MQTT协议将关键数据上传至华为云物联网平台,支持Android手机APP和Windows上位机远程监测与控制。同时,系统具备本地LCD数据显示与蜂鸣器异常报警功能,支持本地按键控制操作。整套系统功能完善,响应灵敏,运行稳定

626

Django middleware中间件

1.什么是Django中间件 2.Django中间件的执行逻辑 3.实现自定义中间件 1.什么是DJango中间件 Django中间件是一个类; 请求前后在合适的时机执行相应的方法; 可以通过在settings文件中配置MIDDLEWARE_CLASSES属性来设置使用何种中间件。 MIDDLEWARE = [ # 安全中间件,处理请求应答安全的处理 'django.middleware...

jstang的博客 3811

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

django<MiddleWare中间件>

MiddleWare中间件 1、Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中 提前处理,此时中间件就上场了。 django在settings模块中,有一个MIDDLEWARE_CLASSES变量,其中每一个元素就是一个中间件。 在settings.py文件中: ...

Doris-wxy 261

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Django中间件MiddleWare

一、什么是中间件   中间件是一个用来处理Django的请求和响应的框架级别的钩子。   中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。 我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下图的MIDDLEWARE配置项。 ...

weixin_30312557的博客 171

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Django 中间件Middleware

中间件(Middleware) 用法:     django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。 setting.py MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'dja...

wbdream's heaven 285

Django中Middleware中间件

Django中Middleware中间件 1 Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法。实际上当我们想在发起请求到服务器views处理函数,我们想对请求做一些提前处理,此时中间件就上场了。 django在settings模块中,有一个MIDDLEWARE_CLASSES变量,其中每一个...

weixin_30713953的博客 122

小白IT:Django框架—中间件Middleware

文章目录一、Djang中的中间件1.为什么使用中间件2.中间件介绍Django请求响应的生命周期二、自定义中间件1.中间件可重写的方法2.中间件使用自定义中间件settings中配置自定义中间件process_request多个中间件中process_request方法的执行过程视图函数loginmiddlewares.py文件settings.py中配置自定义中间件process_response多个中间件中process_response方法的执行过程request中主动返回HttpResponse运行

yidianyidei的博客 2942

Django Middleware 中间件

Django Middleware中间件 中间件字符串导入方式settins.py -> MIDDLEWARE 中间件的放置位置 用户请求时,最先是从中间件,全部按顺序执行中间件又有两种,接收和返回的 接收请求的中间件,request 返回请求的中间件, response 请求过来: 中间件:拦截一部分请求;比如验证session, 没有登录的 ...

diaoqin7781的博客 263

python middleware模块_django之中间件middleware

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES变量,其中每一个元素就是一个中间件,如下图。与mange.py在同一目录下的文件夹 xxx/middleware下的auth.py文件中...

weixin_39754398的博客 189

Django Middleware中间件

中间件Middleware 中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性,其它的MVC框架也有这个功能 Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出 使用场景: 1)当某些操作在每次请求或响应时都会执行时,可以写在中间件里面 比如,每次发送post请求都要进行CSRF验证,就把CSRF验证的代码写在中间件中 设计思想: 1)面向切面编程、无侵害式编程 2)不用直接修改框架源码,就可以达到自己

weixin_47906106的博客 372

Django 中间件 Middleware

中间件 Middleware是Django请求/响应处理的插件框架。它是一个轻巧的低级&amp;amp;amp;amp;amp;quot;插件&amp;amp;amp;amp;amp;quot;系统,用于全局改变Django的输入或输出。 每个中间件组件负责执行某些特定功能。例如,Django包含一个中间件组件 AuthenticationMiddleware,它将用户与使用会话的请求相关联。 该文档介绍了中间件的工作原理,如何激活中间件以及如何编写自己的中间件。Django附带了一些你可以

wanglei_storage的博客 2111

中间件Django Middleware

中间件的原理 配置中间件 首先先新建一个py文件: from django.utils.deprecation import MiddlewareMixin class MyMiddleware(MiddlewareMixin): def __init__(self,get_response=None): super().__init__(get_response) ...

dremcl的博客 182

Django中的中间件(middleware)

一、middleware(中间件) 1、什么是中间件 问题:如何过滤掉没有登陆就访问其他页面? 解决方法 使用装饰器(但是我们要过滤的页面很多,这个方法就很不方便了) 使用中间件(使用此方法要注意,中间件是全局操作,所以要慎用) 概念: 中间件是一个用来处理Django的请求和响应的一个类,可以改变全局范围内Django的输入和输出。简单理解就是中间件是帮助我们在视图函数执行之前和执...

Taneost的博客 431

django 浅谈中间件 middleware

django中有中间件middleware在我们项目settings中的 MIDDLEWARE中 下面浅谈各个中间件含义以及自定义用法: django.middleware.security.SecurityMiddleware’ 一些安全设置,比如XSS脚本过滤。 django.contrib.sessions.middleware.SessionMiddleware se...

DevOps 2296
上一篇: Django中models字段含义、用法
下一篇: logging日志模块
AggressionStorm
博客等级 码龄9年 6粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值