• Django 中间件


    django:

    • 中间件
    • csrf
    • 缓存
    • 信号

    一 、 中间件

    Django的基本生命周期:

      用户发起一次请求到url,再转发给视图函数,视图函数把数据取出来再把模板拿出来,最后进行渲染返回给用户

    Django带有中间件的生命周期:

    中间件比作是横者的管

      请求来的是后先通过中间件,再到路由匹配映射到view视图里,在view视图里的逻辑执行完了后再通过中间件返回给用户

     每个中间件都必须继承这个类 MiddlewareMixin 

    class MiddlewareMixin(object):    #中间件必须继承这个类
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            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',
        "md.hxl.HXL",    #自己写的中间件
        "md.hxl.GYC",    #自己定制的中间件
    ]
    

      

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class LBS(MiddlewareMixin):
        def process_request(self,request):
            print("lbs-->process_request")
            #return HttpResponse("403。。。")  #如果在这里加上return那么将不会走到views和其他中间件,从走过的中间件的process_response返回
    
        def process_response(self,request,response):
            print("lbs-->process_response")
            return response
    
    class HXL(MiddlewareMixin):
        def process_request(self,request):
            print("HXL-->process_request")
    
        def process_response(self,request,response):
            print("HXL-->process_response")
            return response
    
    class GYC(MiddlewareMixin):
        def process_request(self,request):
            print("gyc-->process_request")
    
        def process_response(self,request,response):#必须有三个参数
            """
    
            :param request:
            :param response: views返回的数据
            :return: 必须返回response
            """
            print("gyc-->process_response")
            return response
    
    #执行的顺序
    #HXL-->process_request
    #gyc-->process_request
    #views
    #gyc-->process_response
    #HXL-->process_response
    
    
    #直接return的顺序
    #lbs-->process_request
    #lbs-->process_response

    如果 process_request 函数有返回值的话就不再走其他中间件,就像csrf一样。

    优化版

    自定制中间件需要继承的类

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class MyMiddlewareMixin(object):#自己写一个中间件继承的类
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MyMiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                #执行当前中间件的process_request
                response = self.process_request(request)
            if not response:
                #执行下一个中间件的__call__
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                #执行当前中间件的process_response
                response = self.process_response(request, response)
            return response
    
    
    
    
    
    class LBS(MyMiddlewareMixin):
        def process_request(self,request):
            print("lbs-->process_request")
            return HttpResponse("403。。。")  #如果在这里加上return那么将不会走到views和其他中间件,从走过的中间件的process_response返回
    
        def process_response(self,request,response):
            print("lbs-->process_response")
            return response
    
    class HXL(MyMiddlewareMixin):
        def process_request(self,request):
            print("HXL-->process_request")
    
        def process_response(self,request,response):
            print("HXL-->process_response")
            return response
    
    class GYC(MyMiddlewareMixin):
        def process_request(self,request):
            print("gyc-->process_request")
    
        def process_response(self,request,response):#必须有三个参数
            """
    
            :param request:
            :param response: views返回的数据
            :return: 必须返回response
            """
            print("gyc-->process_response")
            return response
    中间件优化版
    process_view(self, request, views, views_args, views_kwargs):

    process_exception(self, request, exception):
    process_exception只对views函数有效 ,对process_vie无效
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class MyMiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MyMiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                #执行当前中间件的process_request
                response = self.process_request(request)
            if not response:
                #执行下一个中间件的__call__
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                #执行当前中间件的process_response
                response = self.process_response(request, response)
            return response
    
    
    
    
    
    class LBS(MyMiddlewareMixin):
        def process_request(self,request):
            """
            在用户请求时执行的函数,拿到请求
            :param request:
            :return:
            """
            print("lbs-->process_request")
            # return HttpResponse("403。。。")  #如果在这里加上return那么将不会走到views和其他中间件,从走过的中间件的process_response返回
        def process_view(self, request, views_func, views_args, views_kwargs):
            """
            在执行views之前调用的函数,获取路由上的参数
            :param request:
            :param views_func:对应的就是views的视图函数
            :param views_args:参数列表
            :param views_kwargs:关键字参数
            :return:
            """
            print("lbs-->process_view")
            print(views_func, views_args, views_kwargs)
    
    
        def process_response(self,request,response):
            """
            在返回数据时执行的函数,拿到返回的数据
            :param request:
            :param response: views返回的数据
            :return: 必须返回response
            """
            print("lbs-->process_response")
            return response
    
        def process_exception(self, request, exception):
            """
            在异常触发时执行的函数,拿到异常信息
            报错以后调用的函数,如果没处理则到下一个异常函数处理,都没处理则抛异常
            :param request:
            :param exception:异常信息
            :return 如果return了就不往下走,返回值返回给用户
            """
            print("lbs-->process_exception",exception)
    
    class HXL(MyMiddlewareMixin):
        def process_request(self,request):
            print("HXL-->process_request")
    
        def process_view(self, request, views, views_args, views_kwargs):
            print("HXL-->process_view")
    
    
        def process_response(self,request,response):
            print("HXL-->process_response")
            return response
    
        def process_exception(self, request, exception):
            print("HXL-->process_exception")
    
    class GYC(MyMiddlewareMixin):
        def process_request(self,request):
            print("gyc-->process_request")
    
        def process_view(self, request, views, views_args, views_kwargs):
            print("gyc-->process_view")
    
    
        def process_response(self,request,response):#必须有三个参数
            """
    
            :param request:
            :param response: views返回的数据
            :return: 必须返回response
            """
            print("gyc-->process_response")
            return response
    
        def process_exception(self, request, exception):
            print("gyc-->process_exception")
    View Code

    process_template_response(self,request,response)

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    class Foo:
        def __init__(self,request,html):
            self.req=request
            self.html=html
        def render(self):
            return render(self.req,self.html)
    
    def test(request,nid):
    
        print("views")
        return Foo(request,"abc.html")
    View Code

    返回的对象里有render的是后执行

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class MyMiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MyMiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                #执行当前中间件的process_request
                response = self.process_request(request)
            if not response:
                #执行下一个中间件的__call__
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                #执行当前中间件的process_response
                response = self.process_response(request, response)
            return response
    
    
    
    
    
    class LBS(MyMiddlewareMixin):
        def process_request(self,request):
            """
            在用户请求时执行的函数,拿到请求
            :param request:
            :return:
            """
            print("lbs-->process_request")
            # return HttpResponse("403。。。")  #如果在这里加上return那么将不会走到views和其他中间件,从走过的中间件的process_response返回
        def process_view(self, request, views_func, views_args, views_kwargs):
            """
            在执行views之前调用的函数,获取路由上的参数
            :param request:
            :param views_func:对应的就是views的视图函数
            :param views_args:参数列表
            :param views_kwargs:关键字参数
            :return:
            """
            print("lbs-->process_view")
            print(views_func, views_args, views_kwargs)
    
        def process_response(self,request,response):
            """
            在返回数据时执行的函数,拿到返回的数据
            :param request:
            :param response: views返回的数据
            :return: 必须返回response
            """
            print("lbs-->process_response")
            return response
    
        def process_exception(self, request, exception):
            """
            在异常触发时执行的函数,拿到异常信息
            报错以后调用的函数,如果没处理则到下一个异常函数处理,都没处理则抛异常
            :param request:
            :param exception:异常信息
            :return 如果return了就不往下走,返回值返回给用户
            """
            print("lbs-->process_exception",exception)
    
        def process_template_response(self,request,response):
            """
            返回的对象如果有render方法那么就会执行
            :param request:请求信息
            :param response:返回的对象
            :return:
            """
            print("lbs-->process_template_response")
            return response
    
    class HXL(MyMiddlewareMixin):
        def process_request(self,request):
            print("HXL-->process_request")
    
        def process_view(self, request, views, views_args, views_kwargs):
            print("HXL-->process_view")
    
    
        def process_response(self,request,response):
            print("HXL-->process_response")
            return response
    
        def process_exception(self, request, exception):
            print("HXL-->process_exception")
    
        def process_template_response(self,request,response):
            print("HXL-->process_template_response")
            return response
    
    class GYC(MyMiddlewareMixin):
        def process_request(self,request):
            print("gyc-->process_request")
    
        def process_view(self, request, views, views_args, views_kwargs):
            print("gyc-->process_view")
    
    
        def process_response(self,request,response):#必须有三个参数
            """
    
            :param request:
            :param response: views返回的数据
            :return: 必须返回response
            """
            print("gyc-->process_response")
            return response
    
        def process_exception(self, request, exception):
            print("gyc-->process_exception")
    
        def process_template_response(self,request,response):
            print("gyc-->process_template_response")
            return response
    process_template_response

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

    • process_request(self,request)    #在请求到了之前就已经执行了,比如csrf,请求头的过滤
    • process_view(self, request, callback, callback_args, callback_kwargs)    
    • process_template_response(self,request,response)    #在views结束后时执行的
    • process_exception(self, request, exception)
    • process_response(self, request, response)
  • 相关阅读:
    企业面试题|最常问的MySQL面试题集合(一)
    史上最全的大厂Mysql面试题在这里
    Linux运维必会的100道MySql面试题之(一)
    mysql数据库基础命令(一)
    MySQL基础入门之常用命令介绍
    MySQL数据库主从同步实战过程
    MySQL数据库入门备份数据库
    MySQL数据库入门多实例配置
    MySQL数据库入门常用基础命令
    运维LVS三种模式十种调度算法
  • 原文地址:https://www.cnblogs.com/shizhengwen/p/6958654.html
Copyright © 2020-2023  润新知