• Django之Middleware(中间件)


    中间件

      django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

      在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件(内置) 

      详细:https://docs.djangoproject.com/en/2.2/ref/middleware/#security-middleware 

    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 ]

      中间件中可以定义五个方法,分别是:

    • 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)

      以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

    Django的请求生命周期如图:

     自定义中间件

    创建中间件类

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 from django.shortcuts import HttpResponse
     5 from django.utils.deprecation import MiddlewareMixin
     6 
     7 
     8 class M1(MiddlewareMixin):
     9 
    10     def process_request(self, request):
    11         """
    12         内部已经帮我们返回
    13         如果我们自己加上返回值,在1.1版本前直接在当前中间件的process_response方法返回
    14         在1.7 1.8版本后要跳到最后一个中间件的process_response方法一层层的返回
    15         :param request:
    16         :return:
    17         """
    18         print('m1.process_request')
    19 
    20     def process_view(self, request, callback, callback_args, callback_kwargs):
    21         """
    22         得到当前请求的执行视图函数名字
    23         :param request:
    24         :param callback:
    25         :param callback_args:
    26         :param callback_kwargs:
    27         :return:
    28         """
    29         print('m1.process_view')
    30         print(callback)
    31         # 如果这里执行callback(就是视图函数的名字)函数,下面每一个中间件的process_view方法都不走了,直接返回执行视图函数的结果
    32         # 如果这里不执行callback视图函数方法,那么继续走下面中间件的process_view,如果都没执行(这里又有加装饰器的作用了,
    33         # 如果视图函数要加装饰器,那么这里加上装饰器)再走路由匹配,这样为视图函数巧妙的加上装饰器了
    34 
    35         # response = callback(request, *callback_args, **callback_kwargs)
    36         # return response
    37 
    38     def process_response(self, request, response):
    39         """
    40         在这个环节已经通过了路由系统执行当前请求的视图函数了,一层层的返回字符串给用户
    41         :param request:
    42         :param response:
    43         :return:
    44         """
    45         print('m1.process_response')
    46         return response
    47 
    48     def process_exception(self, request, exception):
    49         print('m1.process_exception')
    50 
    51     def process_template_response(self, request, response):
    52         """
    53         视图函数的返回值如果有render方法,才触发这个函数执行
    54         :param request:
    55         :param response:
    56         :return:
    57         """
    58         print('m1.process_template_response')
    59         return response
    60 
    61 
    62 class M2(MiddlewareMixin):
    63 
    64     def process_request(self, request):
    65         print('m2.process_request')
    66 
    67     def process_view(self, request, callback, callback_args, callback_kwargs):
    68         print('m2.process_view')
    69 
    70     def process_response(self, request, response):
    71         print('m2.process_response')
    72         return response
    73 
    74     def process_exception(self, request, exception):
    75         print('m2.process_exception')

    注册中间件

     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     'md.M1',
    10     'md.M2',
    11 ]

     1.路由

    urlpatterns = [
        path('index/', views.index),
    ]
    

    2.视图

     1 from django.shortcuts import render, HttpResponse
     2 
     3 
     4 class Foo:
     5     def __init__(self, request, status, message):
     6         self.request = request
     7         self.status = status
     8         self.message = message
     9 
    10     def render(self):
    11         import json
    12         result = {
    13             'status': self.status,
    14             'message': self.message
    15         }
    16         return HttpResponse(json.dumps(result))
    17 
    18 
    19 def index(request):
    20     # print('index执行视图函数')
    21     # return HttpResponse('.........')
    22     return Foo(request, True, "错误信息")

    我把几个函数都写在一起分步骤测试的  测试如下图:(正常情况如上图请求生命周期,process_exception和process_template_response如下)  

    上图测试的process_exception

    总结下process_exception方法触发的机制流程图:

    下图是测试process_template_response:

     

    总结下process_template_response:视图函数的返回值如果有render方法,才触发这个函数执行

    总结:

         中间件是有序的,从上到小依次执行,本质是因为一个列表

        应用:如果要对请求批量操作的时候就用中间件做

        0.对用户请求缓存中有,我就直接给你,没有就执行视图后续操作(从内存拿数据比从磁盘快多了嘛)

        1.做黑名单

        2.对所有请求日志的记录

        3.做认证权限

        4.装饰器局部使用,全局使用啊

        5.自己也可以做csrf_token认证

          等等很多的看需求

  • 相关阅读:
    阿里云能耗宝助力华聚公司实现产品绿色升级
    最佳实践|从Producer 到 Consumer,如何有效监控 Kafka
    漫画 | 新一代软件架构会影响到谁?
    MongoDB :第七章:总结一下学习MongoDB的心得
    面试:第十二章:所有总结
    技术汇总:第十二章:技术总览
    接口文档:第二章:使用Swagger接口的文档在线自动生成
    为何你炒的肉又硬又柴?原来是忽略了关键1步,大厨教你正确做法
    IKEA bugs All In One
    Korean Keyboard All In One
  • 原文地址:https://www.cnblogs.com/Alexephor/p/11272839.html
Copyright © 2020-2023  润新知