Django中间件

什么是中间件?

官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。

 

中间件怎么用?有什么用?

说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下图的MIDDLEWARE配置项。

 
<wiz_code_mirror>
 
 
 
9
 
 
 
 
 
1
MIDDLEWARE = [
2
    'django.middleware.security.SecurityMiddleware',
3
    'django.contrib.sessions.middleware.SessionMiddleware',
4
    'django.middleware.common.CommonMiddleware',
5
    'django.middleware.csrf.CsrfViewMiddleware',
6
    'django.contrib.auth.middleware.AuthenticationMiddleware',
7
    'django.contrib.messages.middleware.MessageMiddleware',
8
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
9
]
 
 
一次完整的HTTP过程
 
文洲的博客
官方文档对中间件的解释

Django中7个默认中间件的作用

<wiz_code_mirror>
 
 
 
10
 
 
 
 
 
1
MIDDLEWARE = [
2
    'django.middleware.security.SecurityMiddleware',
3
    'django.contrib.sessions.middleware.SessionMiddleware',
4
    'corsheaders.middleware.CorsMiddleware',
5
    'django.middleware.common.CommonMiddleware',
6
    'django.middleware.csrf.CsrfViewMiddleware',
7
    'django.contrib.auth.middleware.AuthenticationMiddleware',
8
    'django.contrib.messages.middleware.MessageMiddleware',
9
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
10
]
 
 
1、django.middleware.security.SecurityMiddleware
安全中间件官方文档的解释:
如果您的部署情况允许,通常最好让您的前端Web服务器执行该服务提供的功能SecurityMiddleware这样,如果存在Django不提供的请求(例如静态媒体或用户上传的文件),它们将具有与对Django应用程序的请求相同的保护。
pass,官方文档都看不懂
 
2、django.contrib.sessions.middleware.SessionMiddleware
<wiz_code_mirror>
 
 
 
x
 
 
 
 
 
1
class SessionMiddleware(MiddlewareMixin):
2
    def __init__(self, get_response=None):
3
        self.get_response = get_response
4
        engine = import_module(settings.SESSION_ENGINE)
5
        self.SessionStore = engine.SessionStore
6

7
    def process_request(self, request):
8
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)    # 从request中获取COOKIE
9
        request.session = self.SessionStore(session_key)    # 在从SessionStore(缓存)中取到session
 
 
然后在执行视图函数
然后执行responce
<wiz_code_mirror>
 
 
 
 
 
 
 
 
 
1
    def process_response(self, request, response):
2
        """
3
        If request.session was modified, or if the configuration is to save the
4
        session every time, save the changes and set a session cookie or delete
5
        the session cookie if the session has been emptied.
6
        """
7
        try:
8
            accessed = request.session.accessed    # 设置为True
9
            modified = request.session.modified    # 设置为True
10
            empty = request.session.is_empty()     # 设置为True
11
        except AttributeError:
12
            pass
13
        else:
14
            # First check if we need to delete this cookie.
15
            # The session should be deleted only if the session is entirely empty
16
            if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
17
                response.delete_cookie(
18
                    settings.SESSION_COOKIE_NAME,
19
                    path=settings.SESSION_COOKIE_PATH,
20
                    domain=settings.SESSION_COOKIE_DOMAIN,
21
                )
22
            else:
23
                if accessed:
24
                    # 大概意思就是django中间件对response进行了修改,然后将Cookie添加进去,构建新的headers
25
                    patch_vary_headers(response, ('Cookie',))    
26
                if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
27
                    if request.session.get_expire_at_browser_close():
28
                        max_age = None
29
                        expires = None
30
                    else:
31
                        # 获取session的时效
32
                        max_age = request.session.get_expiry_age()
33
                        expires_time = time.time() + max_age
34
                        expires = cookie_date(expires_time)
35
                    # Save the session data and refresh the client cookie.
36
                    # Skip session save for 500 responses, refs #3881.
37
                    if response.status_code != 500:
38
                        try:
39
                            request.session.save()    # 进行数据库更新操作
40
                        except UpdateError:
41
                            raise SuspiciousOperation(
42
                                "The request's session was deleted before the "
43
                                "request completed. The user may have logged "
44
                                "out in a concurrent request, for example."
45
                            )
46
                        response.set_cookie(
47
                            settings.SESSION_COOKIE_NAME,
48
                            request.session.session_key, max_age=max_age,
49
                            expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
50
                            path=settings.SESSION_COOKIE_PATH,
51
                            secure=settings.SESSION_COOKIE_SECURE or None,
52
                            httponly=settings.SESSION_COOKIE_HTTPONLY or None,
53
                        )
54
        return response
 
 
这篇博客写的非常好!
 
原文地址:https://www.cnblogs.com/pontoon/p/10216904.html