深入理解Django的中间件middleware

深入理解 Django 的中间件 Middleware

Django 的中间件是一种可插拔的方式,可以处理用户请求和响应的过程,常用于处理日志、安全、缓存、权限等。本文介绍如何使用 Django 的中间件,并提供两个示例说明。

1. 中间件的基本结构

Django 中间件的基本结构包括了三个方法:

  • __init__(self, get_response):在中间件被初始化时执行,可用于对中间件进行设定。
  • __call__(self, request):每次接受请求时都会执行,可用于处理请求前的逻辑。
  • process_response(self, request, response):在视图响应后执行,可用于处理响应后的逻辑。

这三个方法中,只有 __call__ 是必须实现的方法,其他两个方法是可选的。

下面看一个简单的中间件示例。

class SwapMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.url, request.path = request.path, request.url
        response = self.get_response(request)
        return response

上面代码中,定义了一个简单的中间件类 SwapMiddleware。该中间件只有 __init____call__ 两个方法。在 __init__ 方法中,我们通过接收 get_response 参数来保存访问视图函数时的回调函数。而在 __call__ 方法中,我们将 request 的 url 和 path 交换位置,并调用回调函数 self.get_response(request) 拿到响应。(该例子是将 request 中的 url 和 path 交换位置,纯属娱乐,开发中并不会使用)

2. 中间件的配置

Django 的中间件需要在 django.settings.py 文件中进行配置。中间件按照顺序依次执行,如果前面的中间件处理了请求,那么后面的中间件将不再执行处理逻辑。这点需结合中间件的定义来理解。一般而言,中间件配置有两个关键字:

  • MIDDLEWARE:是一个中间件列表,最好指定顺序。
  • MIDDLEWARE_CLASSES:是一个中间件类路径列表,大多数 legacy 代码使用这个指令。

下面是一个完整的配置示例:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

上面代码中,定义了 Django 官方推荐的中间件顺序。

3. 示例一:处理请求头

假设我们的网站需要验证每个请求中是否有指定的请求头 Authorization,并获取请求头的值作为当前用户的 token,那么我们可以编写一个自定义中间件来完成该功能。代码如下:

class TokenMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        authorization = request.META.get('HTTP_AUTHORIZATION')
        request.token = authorization.split()[1] if authorization else None
        response = self.get_response(request)
        return response

上面这个自定义中间件的作用是通过 request.META 获取请求头 Authorization,并从中获取值作为 token 存储在 request 对象中,便于后续的视图函数使用。

4. 示例二:限制访问频率

假设我们的网站需要限制用户访问频率,每秒钟只允许访问一次。那么我们可以编写一个自定义中间件来处理该功能。代码如下:

import time

class RateLimitMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.limits = {}  # 记录各 IP 的上次访问时间

    def __call__(self, request):
        ip = self.get_client_ip(request)
        now = time.time()
        last_visit_time = self.limits.get(ip, 0)
        if now - last_visit_time < 1:
            return HttpResponseForbidden('您访问过于频繁,请稍后再试。')
        self.limits[ip] = now
        response = self.get_response(request)
        return response

    def get_client_ip(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip

上面代码中,自定义中间件 RateLimitMiddleware 记录了各个用户的最近一次访问时间,如果与当前时间的时间差小于 1 秒,则返回一个 403 Forbidden 的响应即可。

值得注意的是,这个方法获取 IP 的方式,因网络架构的不同,可能无法获取到用户真实 IP。但是我们可以通过 Nginx 的 proxy_set_header 指令来弥补,具体可参考资料。

5. 总结

本文简单介绍了 Django 中间件的基本结构和配置方法,并提供了两个常用的示例说明,分别用于处理请求头和限制访问频率。中间件是 Django 一种强大的可插拔机制,可以用于丰富项目功能,并提高代码的可读性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Django的中间件middleware - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • ubuntu16.04自动设置行号的步骤详解

    请注意查看下面的标准markdown格式文本。 Ubuntu16.04自动设置行号的步骤详解 为了提高Linux系统的编程效率,我们有时候需要在vim等编辑器中开启行号功能,方便我们进行代码编写,并且在调试过程中更便捷地排查错误。在下面的几步中,我将详细介绍如何在Ubuntu16.04中自动设置行号功能。 步骤一:检查vim是否已安装 在终端中输入以下命令来…

    人工智能概览 2023年5月25日
    00
  • Python分布式异步任务框架Celery使用教程

    Python分布式异步任务框架Celery使用教程 简介 Celery是Python编写的分布式异步任务队列,是一个优秀的基于消息传递的任务队列。Celery支持任务调度和消息分发,可以根据用户的需求创建多个任务队列,优化用户的任务处理效率。 安装 安装Celery可以使用官方推荐的方式通过pip进行安装。例如: pip install celery 安装好…

    人工智能概览 2023年5月25日
    00
  • 详解SpringBoot Mongo 自增长ID有序规则

    概述 在MongoDB中,自增长ID经常被用作主键并且遵循基于时间的排序规则。在Spring Boot和MongoDB集成的开发中,实现自增长ID有序规则可以为数据查询和数据排序提供更好的支持。 实现方法 在Spring Boot中使用MongoDB默认提供的ObjectId作为主键,该主键是基于时间的,自增长ID有序规则下可以保证默认按照_id升序排列。 …

    人工智能概论 2023年5月25日
    00
  • java使用电脑摄像头识别二维码

    Java使用电脑摄像头识别二维码攻略 简介 本攻略主要介绍如何使用Java语言操作电脑摄像头,并借助相关库识别二维码。 准备工作 安装Java运行环境(JRE) 下载并安装Java开发工具(如Eclipse、IntelliJ IDEA等) 下载安装OpenCV库(可选,用于操作电脑摄像头) 操作电脑摄像头 方案一:使用JMF库 Java Media Fram…

    人工智能概论 2023年5月25日
    00
  • Django使用HTTP协议向服务器传参方式小结

    下面是关于“Django使用HTTP协议向服务器传参方式小结”的详细讲解。 HTTP协议传参方式小结 在Django中,我们常常需要在HTTP请求中向服务器传递参数。这个参数可以是请求头、请求体或请求URL中的一部分。通常情况下,我们可以使用以下四种方式来传递参数: GET方法 GET方法是最简单的一种HTTP请求方法,它将请求参数放在URL的后面,形如/y…

    人工智能概览 2023年5月25日
    00
  • python生成requirements.txt文件的推荐方法

    生成requirements.txt文件是Python项目开发中非常重要的一步。它可以帮助我们记录和管理项目所依赖的第三方库及其版本号,方便其他人分析项目的依赖关系和在其他机器上重复安装环境。下面我将为大家介绍一种推荐的方法来生成requirements.txt文件。 步骤一:安装pipreqs pipreqs是一个Python库,可以自动生成项目所需的依赖…

    人工智能概览 2023年5月25日
    00
  • 命令行传递参数argparse.ArgumentParser的使用解析

    命令行传递参数是很多Python程序必不可少的功能之一,它使得程序更加灵活、可定制化和易用。Python标准库中的argparse模块提供了解析命令行参数的工具,可以很方便地实现命令行传递参数的功能。 argparse模块的基本使用 在使用argparse模块之前,需要先导入该模块。下面是一个简单的例子,演示了如何使用argparse模块解析命令行参数: i…

    人工智能概览 2023年5月25日
    00
  • Pytorch中torch.flatten()和torch.nn.Flatten()实例详解

    介绍:在PyTorch中,PyTorch提供了两个函数:torch.flatten和torch.nn.Flatten用于将多维张量转换为一维张量。然而它们之间的实现方式和特点略有不同。 Torch.flatten() torch.flatten(input, start_dim=0, end_dim=-1)函数用于将一个输入的多维形状张量展平成形状为“1D”…

    人工智能概论 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部