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)
原文地址:https://www.cnblogs.com/shizhengwen/p/6958654.html