Django中间件看完这篇彻底明白

2022-03-31  本文已影响0人  amyhy

我们在使用python的一些库时,会遇到中间件这个概念,比如scrapy和Django,那么什么是中间件呢?

什么是中间件

中间件就是在目标结果之间进行的额外处理过程,在Django中就是request和response之间进行的处理,相对来说实现起来比较简单,但是要注意它是对全局有效的,可以在全局范围内改变输入和输出结果,因此需要谨慎使用,否则不仅会造成难以定位的错误,而且可能会影响整体性能。

中间件有什么用

如果想要修改HttpRequest或者HttpResponse,就可以通过中间件来实现。

中间件执行流程

在Django中自定义中间件是非常简单的,在settings.py中有一个配置项:

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

只要把添加的中间件配置在这里就可以了。每一个中间件都是一个类,多个中间件可以写在同一个文件,也可以在独立文件中。每个中间件可以包含五个方法:

process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

我在网上找到这么一张图片,说明了请求的数据流在Django中间件当中的执行流程

image.png

中间件函数执行流程

以上这些执行函数将返回None或者HttpResponse对象,如果返回None,则交给下一个中间件的对应函数处理;如果返回HttpResponse对象,则将其返回给用户

在这些中间件的执行函数中,我们最常用的就是process_request和process_response函数,通常用来在视图函数处理前和视图函数处理后执行一些相应的操作,这个要根据我们的业务需求,选择不同的处理过程。例如:进行登陆认证,因为必须要在视图函数处理前进行认证,我们可以在process_request中处理;携带认证cookies信息,就可以在process_response函数中给response对象增加指定cookies值。

中间件回调函数执行

自定义中间件

from django.utils.deprecation import MiddlewareMixin

class MyCustomMiddleware1(MiddlewareMixin):
    def process_request(self, request):
        print('MyCustomMiddleware1')

    def process_response(self, request, response):
        print('返回 MyCustomMiddleware1')
        return response

class MyCustomMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('MyCustomMiddleware2')

    def process_response(self, request, response):
        print('返回 MyCustomMiddleware2')
        return response
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',
    'MyMiddleware.MyCustomMiddleware1',
    'MyMiddleware.MyCustomMiddleware2'
]

输出结果:

MyCustomMiddleware1
MyCustomMiddleware2
返回 MyCustomMiddleware2
返回 MyCustomMiddleware1

系统中间件的用途

def process_request(self, request):
    session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
    request.session = self.SessionStore(session_key)

process_response函数中,给response对象设置SESSION_COOKIE_NAME值和过期时间等。

response.set_cookie(
   settings.SESSION_COOKIE_NAME,
   request.session.session_key, max_age=max_age,
   expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
   path=settings.SESSION_COOKIE_PATH,
   secure=settings.SESSION_COOKIE_SECURE or None,
   httponly=settings.SESSION_COOKIE_HTTPONLY or None,
   samesite=settings.SESSION_COOKIE_SAMESITE
)
if 'HTTP_USER_AGENT' in request.META:
    for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
        if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
            raise PermissionDenied('Forbidden user agent')

检查是否需要添加/,主要是根据settings中APPEND_SLASH配置

if self.should_redirect_with_slash(request):
    path = self.get_full_path_with_slash(request)
else:
    path = request.get_full_path()

在process_response函数中,会判断是否需要把404的请求重新定向到我们需要的页面

https://cloud.tencent.com/developer/article/1631561

上一篇下一篇

猜你喜欢

热点阅读