11.Django|中间件

 中间件

中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

Django的中间件的定义:

Middleware is a framework of hooks into Django’s request/response processing. <br>It’s a light, low-level “plugin” system for globally altering Django’s input or output.

Django默认的Middleware

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

每一个中间件都有具体的功能。

django默认7个中间件,其实就是一个类。

 django请求周期

 自定义中间件

中间件一共有四个方法:

process_request

process_view

process_exception

process_response

当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin

需要导入:

from django.utils.deprecation import MiddlewareMixin

process_response是在中间件里边一层层的传,先到第一个个中间件,再到第二个,是依次执行的

 视图函数在校验时候,可以把校验写在某个中间件里边去,在这里边写一次,进来的所有请求都可以校验下,不用一个个加装饰器了。

from django.utils.deprecation import MiddlewareMixin
class CustomerMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware1 process_request')

class CustomerMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware2 process_request')
'app01.my_middlewares.CustomerMiddleware',
'app01.my_middlewares.CustomerMiddleware2',

#这两个中间件里边的process_request依次执行; 它是全局的逻辑处理
CustomerMiddleware1 process_request
CustomerMiddleware2 process_request
index  #先走中间件,再进视图函数打印它
[15/Jun/2018 10:01:38] "GET /index/ HTTP/1.1" 200 5
from django.shortcuts import render, HttpResponse

# Create your views here.
def index(request):
    print('index')
    return HttpResponse("INDEX")  
    #相应体就是INDEX这个字符串,先执行后边的中间件,先交给CustomerMiddleware2的process_response,执行完自己的逻辑,又把response交给了它上一个中间件的process_response,然后执行它的逻辑打印,就这样子传接力棒
def index_new(request):

    return HttpResponse('index_new')
from django.utils.deprecation import MiddlewareMixin
class CustomerMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware1 process_request')
    def process_response(self, request,response): #response就是HttpResponse(INDEX)相应体对象
        print('CustomeerMiddleware1 process_request')
        return response  #它必须要有返回值,就像接力棒一层层传给别人;在process_request里边必须要写返回值。

class CustomerMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware2 process_request')
    def process_response(self, request,response):
        print('CustomeerMiddleware2 process_request')
        return response
CustomerMiddleware1 process_request
CustomerMiddleware2 process_request
index
CustomeerMiddleware2 process_request
CustomeerMiddleware1 process_request
[15/Jun/2018 10:11:12] "GET /index/ HTTP/1.1" 200 5
#相应体就是INDEX这个字符串,先执行后边的中间件,先交给CustomerMiddleware2的process_response,执行完自己的逻辑,
又把response交给了它上一个中间件的process_response,然后执行它的逻辑打印,就这样子传接力棒

如果非要在process_request加个返回值,

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class CustomerMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware1 process_request')
        return HttpResponse('forbidden..')

    def process_response(self, request,response): #response就是HttpResponse(INDEX)相应体对象
        print('CustomeerMiddleware1 process_request')
        return response  #它必须要有返回值,就像接力棒一层层传给别人

class CustomerMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware2 process_request')
    def process_response(self, request,response):
        print('CustomeerMiddleware2 process_request')
        return response
CustomerMiddleware1 process_request
CustomeerMiddleware1 process_request
[15/Jun/2018 10:29:42] "GET /index/ HTTP/1.1" 200 11

#访问http://127.0.0.1:8000/index/打印的是forbidden..

没有执行中间件2的内容,也没有执行视图。

 url请求中间件1的process_request的时候,一旦加了返回值,直接把相应体交给自己的process_response,交给浏览器。一下子给拦截了。应用场景:拦截,你的ip频率太高;session进行校验的时候没有登录也给你拦截下来。

process_view

[15/Jun/2018 10:40:45] "GET /index/ HTTP/1.1" 200 5
CustomerMiddleware1 process_request
CustomerMiddleware2 process_request
CustomerMiddleware1:process_view
CustomerMiddleware2:process_view
index
CustomeerMiddleware2 process_request
CustomeerMiddleware1 process_request
#Author:Kris

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class CustomerMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware1 process_request')
        #return HttpResponse('forbidden..')
    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("CustomerMiddleware1:process_view")

    def process_response(self, request,response): #response就是HttpResponse(INDEX)相应体对象
        print('CustomeerMiddleware1 process_request')
        return response  #它必须要有返回值,就像接力棒一层层传给别人

class CustomerMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware2 process_request')
    def process_response(self, request,response):
        print('CustomeerMiddleware2 process_request')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        #print("===>",callback) #===> <function index at 0x0000000003DE11E0> 视图函数
        #在进入到2的视图函数的时候,把相应体返回了 123,那么视图函数就不执行了,接着往下执行process_response
        print("===>",callback(callback_args))

        print("CustomerMiddleware2:process_view")
        ret = callback(callback_args)      ###可以进行拦截。
        return ret  #把它的结果返回了就可以拿到index了
        #return HttpResponse('123')

process_exception

CustomerMiddleware1 process_request
CustomerMiddleware2 process_request
CustomerMiddleware1:process_view
CustomerMiddleware2:process_view
index    #打印完视图就报错了,报错没有拿到相应体HttpResponse(index),直接走下面的process_exception
CustomeerMiddleware2 process_exception
CustomeerMiddleware1 process_exception
Internal Server Error: /index/ 出错

  CustomeerMiddleware2 process_request
  CustomeerMiddleware1 process_request

#Author:Kris

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class CustomerMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware1 process_request')
        #return HttpResponse('forbidden..')
    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("CustomerMiddleware1:process_view")

    def process_response(self, request,response): #response就是HttpResponse(INDEX)相应体对象
        print('CustomeerMiddleware1 process_request')
        return response  #它必须要有返回值,就像接力棒一层层传给别人
    def process_exception(self, request, exception):
        print('CustomeerMiddleware1 process_exception')

class CustomerMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print('CustomerMiddleware2 process_request')
    def process_response(self, request,response):
        print('CustomeerMiddleware2 process_request')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        #print("===>",callback) #===> <function index at 0x0000000003DE11E0> 视图函数
        #在进入到2的视图函数的时候,把相应体返回了 123,那么视图函数就不执行了,接着往下执行process_response
        #print("===>",callback(callback_args))

        print("CustomerMiddleware2:process_view")
        # ret = callback(callback_args)
        # return ret  #把它的结果返回了就可以拿到index了
        #return HttpResponse('123')
    def process_exception(self, request, exception):
        print('CustomeerMiddleware2 process_exception')
        return HttpResponse(exception)  #一旦有一个return了,后边1的process_exception就不执行了
CustomerMiddleware1 process_request
CustomerMiddleware2 process_request
CustomerMiddleware1:process_view
CustomerMiddleware2:process_view
index
CustomeerMiddleware2 process_exception
CustomeerMiddleware2 process_request
CustomeerMiddleware1 process_request
[15/Jun/2018 11:34:36] "GET /index/ HTTP/1.1" 200 26

如果把写到1里边,2不要,return HttpResponse(exception) 

CustomerMiddleware1 process_request
CustomerMiddleware2 process_request
CustomerMiddleware1:process_view
CustomerMiddleware2:process_view
index
CustomeerMiddleware2 process_exception
CustomeerMiddleware1 process_exception
CustomeerMiddleware2 process_request
CustomeerMiddleware1 process_request
[15/Jun/2018 11:37:28] "GET /index/ HTTP/1.1" 200 26

应用URL访问过滤 在auth_Demo

如果用户访问的是login视图(放过)

如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect
from authDemo import settings

class AuthMiddleware(MiddlewareMixin):
    def process_request(self, request):
        white_list = settings.WHITE_LIST
        if request.path in white_list:
            return None
        if not request.user.is_authenticated:
            return redirect("/login/")

猜你喜欢

转载自www.cnblogs.com/shengyang17/p/9186160.html