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

科技资讯 投稿 21800 0 评论

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

原文链接:Django笔记二十九之中间件介绍

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

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

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

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

首先,前端发起一个请求,这个请求经由 web 服务器转发给 Django 系统,在进入 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 视图函数进行数据处理

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

2、HttpRequest 和 HttpResponse 介绍

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

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

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

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

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

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

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 做下处理

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

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

process_view

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

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

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

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

那么我们这样设置一个 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('<h2>您的ip被禁止</h2>'
        return None

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

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

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

赞同 (101) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽