zoukankan      html  css  js  c++  java
  • Django中间件

    中间件介绍

    Django中间件是django的门户。它可以用来在全局范围内改变Django的输入和输出,每个中间件都负责做一些特定的功能。

    比如:全局用户身份校验,全局用户访问频率校验,用户访问黑名单。

    说的直白一点:中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作

    只要以后用django开发业务,设计到全局相关的功能,就可以考虑用中间件。

     

    打开Django项目的Settings.py文件,可以看到下图的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',
    ]
    复制代码

    自定义中间件

    中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

    • process_request(self,request)
    • process_view(self, request, view_func, view_args, view_kwargs)
    • process_template_response(self,request,response)
    • process_exception(self, request, exception)
    • process_response(self, request, response)

    重要的两个方法

    process_request:

     

     

    它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,如果是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器。

    由此总结一下:

    1. 中间件的process_request方法是在执行视图函数之前执行的。
    2. 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是从上到下依次执行的。
    3. 不同中间件之间传递的request都是同一个对象

    request_response:

    多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的。

    定义process_response方法时,必须给方法传入两个形参,request和response,并且需要将形参response返回。

    如果你内部自己返回了HttpResponse对象 会将返回给用户浏览器的内容替换成你自己的。

     views.py

    class MD1(MiddlewareMixin):

    def process_request(self, request):
    print("MD1里面的 process_request")

    def process_response(self, request, response):
    print("MD1里面的 process_response")
    return response


    class MD2(MiddlewareMixin):
    def process_request(self, request):
    print("MD2里面的 process_request")
    pass

    def process_response(self, request, response):
    print("MD2里面的 process_response")
    return response

    views.py

    终端输出:

    MD1里面的 process_request
    MD2里面的 process_request
    app01 中的 index视图
    MD2里面的 process_response
    MD1里面的 process_response

    需要了解的三个方法

    process_view

    此方法是在Django路由系统匹配成功之后,视图系统之前执行的,执行顺序按照MIDDLEWARE中的注册顺序从前到后顺序执行的

    process_template_response

    process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法

     自定义的中间件

    class MD1(MiddlewareMixin):

    def process_request(self, request):
    print("MD1里面的 process_request")

    def process_response(self, request, response):
    print("MD1里面的 process_response")
    return response

    def process_view(self, request, view_func, view_args, view_kwargs):
    print("-" * 80)
    print("MD1 中的process_view")
    print(view_func, view_func.__name__)

    def process_template_response(self, request, response):
    print("MD1 中的process_template_response")
    return response


    class MD2(MiddlewareMixin):
    def process_request(self, request):
    print("MD2里面的 process_request")
    pass

    def process_response(self, request, response):
    print("MD2里面的 process_response")
    return response

    def process_view(self, request, view_func, view_args, view_kwargs):
    print("-" * 80)
    print("MD2 中的process_view")
    print(view_func, view_func.__name__)

    def process_template_response(self, request, response):
    print("MD2 中的process_template_response")
    return response

    自定义的中间件

     Views.py

    def index(request):
    print("app01 中的 index视图")

    def render():
    print("in index/render")
    return HttpResponse("O98K")
    rep = HttpResponse("OK")
    rep.render = render
    return rep

    Views.py

     输出结果

    MD1里面的 process_request
    MD2里面的 process_request
    --------------------------------------------------------------------------------
    MD1 中的process_view
    <function index at 0x000001C111B97488> index
    --------------------------------------------------------------------------------
    MD2 中的process_view
    <function index at 0x000001C111B97488> index
    app01 中的 index视图
    MD2 中的process_template_response
    MD1 中的process_template_response
    in index/render
    MD2里面的 process_response
    MD1里面的 process_response

    输出结果

    process_exception

    当视图函数报错的时候自动触发,它的执行顺序也是按照中间件注册顺序的倒序执行。

    中间件的补充:

    ## 中间件
    
    自定义中间件
    
    ~~~
    应用下创建一个文件夹,文件夹下面创建一个xx.py文件
    from django.utils.deprecation import MiddlewareMixin
    class MD1(MiddlewareMixin):
    
        def process_request(self,request):
            
            return None
        def process_response(self,request,response)
            
            return response
    
    
    ~~~
    
    
    
    白名单
    
    ```
    from django.urls import reverse
    from django.shortcuts import (
        redirect,HttpResponse,render
    )
    
    from django.utils.deprecation import MiddlewareMixin
    
    class SessionAuth(MiddlewareMixin):
        
        def process_request(self,request):
            pass
            #白名单
            # print(request.path)
            white_list = [reverse('login'),'/index/']
            if request.path in white_list:
                
                return None
            
            is_login = request.session.get('is_login')
    
            if is_login == True:
    
                return None
            else:
                return redirect('login')
    ```
    
    
    
    # 今日内容
    
    中间件的五个方法
    
    ~~~
    process_request(self,request)
    process_view(self, request, view_func, view_args, view_kwargs)
    process_template_response(self,request,response)
    process_exception(self, request, exception)
    process_response(self, request, response)
    
    ~~~
    
    process_view:
    
    ![img](https://images2018.cnblogs.com/blog/877318/201805/877318-20180523150722556-373788290.png)
    
    
    
    process_exception:视图函数出错,会执行
    
    ![img](https://images2018.cnblogs.com/blog/877318/201805/877318-20180523152523125-1475347796.png)
    
    
    
    process_template_response:
    
    ~~~
    def index(request):
        print("app01 中的 index视图")
      #raise ValueError('出错啦') 
        def render():
            print("in index/render")  
            #raise ValueError('出错啦') #至于render函数中报错了,那么会先执行process_template_response方法,然后执行process_exception方法,
                         #如果是在render方法外面报错了,那么就不会执行这个process_template_response方法了。
    return HttpResponse("O98K") #返回的将是这个新的对象 rep = HttpResponse("OK") rep.render = render return rep
  • 相关阅读:
    130517Dev GridControl建立多行复杂表头(Banded View)时,统计列与对应列无法对齐的解决办法
    C&C++标准库
    Linux操作系统下的多线程编程详细解析
    Ubuntu12.04用户以root身份登录
    ubuntu永久修改主机名
    linux信号 linux signal
    淘宝api 登录验证
    淘宝开店 防骗 易赛加款诈骗|冲q币恶意差评
    面试..
    test
  • 原文地址:https://www.cnblogs.com/wddxx/p/13809882.html
Copyright © 2011-2022 走看看