Django笔记二十九之中间件介绍

本文首发于公众号:Hunter后端
原文链接:Django笔记二十九之中间件介绍

这一节介绍一下 Django 的中间件。

关于中间件,官方文档的解释为:中间件是一个嵌入 Django 系统的 request 和 response 的钩子框架,是一个能够全局改变 Django 输入/输出的系统。

我们可以这样理解,一个 request 请求发送到 Django 系统的过程中,在经过路由和视图的处理前,会先经过一层处理,这个处理操作可以是日志记录,可以是登录验证甚至你想在系统里定义的功能,这个操作就是中间件实现的功能。

接下来我们将通过一个记录请求的 ip 的功能的介绍来介绍一下中间件的实现流程。

以下是本篇笔记目录:

  1. 请求经过 Django 然后返回的流程
  2. HttpRequest 和 HttpResponse 介绍
  3. 中间件的示例介绍
  4. 记录访问 ip 的功能实现

1、请求经过 Django 然后返回的流程

首先,前端发起一个请求,这个请求经由 web 服务器转发给 Django 系统,在进入 Django 系统后会先经过一系列的中间件的功能处理。

这个中间件会在 settings.py 里定义,Django 系统默认自带的中间件列表如下:

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',
]

这些中间件我们也可以根据自己的需求自己定义,比如新加一个登录权限,或者日志记录,或者对输入的参数进行格式化处理也可以,或者自己想要设置的其他功能也行,具体怎么设置在后面介绍。

在中间件处理的流程中,请求会被按照顺序从上往下处理。

这个流程过后,一个 request 请求才会被进行 URL 的路径匹配,如果匹配上,再去找相应的 views 视图函数进行数据处理

views 处理完之后,会形成一个 response,返回,然后再次经历这个中间件处理,因为在每一层中间件中都类似于一种嵌套,所以返回 response 的时候,是从下往上再次处理 response 的。

中间件处理结束之后再被返回出去,给到前端。

在这整个流程处理中,可以说中间件是进行了两次操作,一个是进入的时候处理 request,一个是返回的时候处理 response。

2、HttpRequest 和 HttpResponse 介绍

我们先来看一个视图函数:

def time_view(request):
    now = datetime.datetime.now()
    html = "<h1>now: %s</h1>abc\nabc" % now
    return HttpResponse(html)

当 Django 接收到一个请求,系统会创建一个 HttpRequest 对象,这个对象就是上面的视图函数里的输入参数,request

在对数据进行处理后,系统会返回一个 HttpResponse 对象,这个就是我们 return 的内容。

在一个 HttpRequest 对象里,会包含请求的路径、参数、请求方式、 cookie 等一切请求过来时的数据,我们可以在请求的时候根据需要存取。

在返回的 HttpResponse 中,可以是一个 html 页面,也可以是 json 格式的数据,内容是可以自定义的,只要前端可以做相应的处理。

3、中间件的示例介绍

接下来我们定义一个中间件,结构大致如下:

# huter/middleware.py

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

    def __call__(self, request):

        # 在请求进入视图函数前的可以执行一些操作,针对 request
        print(request.path)
        response = self.get_response(request)
        
        # 在处理完请求后,可以执行一些操作,针对 response
        # log_response_info()
        return response

然后我们在 sttings.py 里引入这个中间件,我们放到 MIDDLEWARE 列表的最下面,说明这个中间件会在其他中间件处理完 request 之后再处理:


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',
    'hunter.middleware.TestMiddleware',
]

在 SimpleMiddleware 这个类里,call() 函数会自动调用,其中有一行,response = self.get_response(request)

在这一行函数之前,可以对请求的 request 做处理,包括我们前面说的各种功能,比如日志、登录验证、参数格式化等

在这一行函数之后,获取了 response,这个就是视图函数返回的 HttpResponse,我们可以在这里对它的 response.status_code 状态码,和 response.content 做处理

比如前面 time_view 函数返回的内容是一个 JsonResponse:

return JsonResponse({"code": 0})

那么在这里我们可以获取然后处理这个 HttpResponse:


def __call__(self, request):

    response = self.get_response(request)

    content = json.loads(response.content)
    content["msg"] = "success"
    response.content = json.dumps(content)
    return response

这里只是一个示例,因为并不是所有的 HttpResponse 都是 json 格式的数据,所以可能需要加一个 try except 做下处理

还有一个功能是我之前做过的,就是在 headers 中加一个特定的字符串,表示是我们系统专有的,用于前端判断,这个很简单,就是在 response 的 headers 参数中加一个键值对:

response.headers['system'] = 'hunter'

以上就是一个最简单的中间件的处理方式。

process_view

除了 call 函数以外,还有一个 process_view() 的函数

这个函数是在 Django 系统调用 views 视图函数前被调用,它的返回值是 None 或者一个 HttpResponse

如果为 None,那么系统会接着调用视图函数,如果是 HttpResponse 作为返回值,说明系统在这里已经处理了请求,不需要再走views视图函数,然后就会直接返回。

我们通过下面的例子来解释这个函数作用。

4、记录访问 ip 的功能实现

假设我们需要禁止某一个或者某一个 ip 列表的请求访问我们的系统

当然,这个操作,在 web 服务器那部分就可以拦截,这里就是单纯举个例子

那么我们这样设置一个 process_view 的功能,在真正执行视图函数(也就是url 匹配上的 view函数)前,取出这个 request 的访问的ip,然后进行判断,如果在 禁止列表,那么则直接返回一个禁止访问的页面。

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


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


    def process_view(self, request, view_func, *view_args, **view_kwargs):
        EXCLUDE_IPS = ['192.168.1.54']
        if 'HTTP_X_FORWARDED_FOR' in  request.META:
            ip =  request.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = request.META['REMOTE_ADDR']
        if ip in EXCLUDE_IPS:
            return HttpResponse('<h1>您的ip被禁止</h1>')
        return None

在这里,我们拿到请求的 ip 地址,去和我们定义的禁止ip列表做比较

如果在禁用列表,则直接返回 HttpResponse,不接着请求我们的服务来

否则,就返回 None,系统接收到 None 之后,会接着往下处理。

如果想获取更多后端相关文章,可扫码关注阅读:

image

原文链接:https://www.cnblogs.com/hunterxiong/p/17347565.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django笔记二十九之中间件介绍 - Python技术站

(0)
上一篇 2023年4月22日
下一篇 2023年4月24日

相关文章

  • Python字符串查找基本操作代码案例

    下面是关于“Python字符串查找基本操作代码案例”的完整攻略: 1. 概述 在Python中,字符串(String)是一种非常常见的数据类型。而在实际编程过程中,我们往往需要查找一个字符串中是否包含某个特定的子串,或者查找某个字符在字符串中的出现位置等。本篇文章将介绍Python字符串查找基本操作的代码案例。 2. 查找特定子串 2.1 方法一 ———— …

    python 2023年5月31日
    00
  • 利用Python实现一个简易的截图工具

    如果想利用Python实现简易的截图工具,可以按照以下步骤来进行操作: 步骤一:安装依赖包 利用Python实现简易截图工具,需要用到第三方包Pillow和tkinter,在使用前确保已经安装了这两个包。 pip install Pillow pip install tkinter 步骤二:创建GUI界面 要实现简易截图工具,需要先创建GUI界面,使用tki…

    python 2023年5月19日
    00
  • Python数学建模库StatsModels统计回归简介初识

    Python数学建模库StatsModels统计回归简介初识 StatsModels是Python数据分析常用的库之一,它是用于拟合和分析各种统计模型的库。其中包括线性回归、广义线性模型、时间序列分析等。本文将简单介绍StatsModels库中的统计回归分析。 一、线性回归 线性回归是一种用于探索两种变量之间关系的统计学方法。其中一个变量被看做是自变量,另一…

    python 2023年6月5日
    00
  • python 中字典嵌套列表的方法

    Python中字典嵌套列表的方法 在Python中,字典嵌套列表是一种常见的数据结构,它可以用来存储和处理复杂的数据。本攻略将详细介绍Python中字典嵌套列表的方法,包括如何创建、访问、添加、删除、修改等方面。 创建字典嵌套列表 在Python中,可以使用花括号{}来创建一个字典,使用方括号[]来创建一个列表。要创建一个字典嵌套列表,可以在字典的值中使用一…

    python 2023年5月13日
    00
  • Python利用正则表达式匹配并截取指定子串及去重的方法

    以下是Python利用正则表达式匹配并截取指定子串及去重的方法的完整攻略: 步骤1:导入re模块 在Python中使用正则表达式需要导入re模块,可以使用以下代码导入: import re 步骤2:编写正则表达式 编写正则表达式是使用正则表达式的第一步。正则表达式是一种用于匹配文本的模式,可以用来查找、替换或截取文本中的特定部分。以下是一些常用的正则表达式元…

    python 2023年5月14日
    00
  • Python入门必须知道的11个知识点

    Python入门必须知道的11个知识点 Python是一种简单易学、功能强大的编程语言,已经得到了广泛的应用。下面是入门Python必须知道的11个知识点,包括变量、数据类型、运算符、条件语句、循环语句、函数、模块、I/O操作、异常处理、面向对象编程和常用的第三方库。 变量 变量是用来存储数据的容器,Python中的变量不需要事先声明数据类型,可以直接赋值。…

    python 2023年6月5日
    00
  • python字符串的一些常见实用操作

    关于“Python字符串的一些常见实用操作”的攻略共分为以下几个方面: 1. 创建字符串 Python中的字符串可以通过单引号、双引号或三引号来创建,其中三引号可以用于创建多行字符串。 示例1:使用单引号和双引号创建字符串 str1 = ‘Hello World’ str2 = "Hello World" print(str1) # 输出…

    python 2023年6月5日
    00
  • python 利用jinja2模板生成html代码实例

    在Python中,我们可以使用jinja2模板引擎生成HTML代码。以下是Python利用jinja2模板生成HTML代码的完整攻略,包含两个示例。 示例1:使用jinja2模板引擎生成HTML代码 以下是一个示例,可以使用jinja2模板引擎生成HTML代码: from jinja2 import Template # 定义模板 template_str …

    python 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部