zoukankan      html  css  js  c++  java
  • Django中间件简单说明

    中间件

    配置文件

    项目主目录中的配置文件是django留给开发者使用的用户级别配置文件

    实际上django有一个自己的默认全局配置文件。

    那么他们的关系如下

    # django默认配置
    from django.conf import global_settings
    
    # 用户级别配置
    from django_middleware import settings
    
    
    from django.conf import settings # 中间人
    # 比如需要引入配置中的某个配置项settings.APPEND_SLASH,那么这样的引入的查找顺序是这样,先去用户级别settings.py文件中去找这个配合,
    如果没有找到,那么会去global_settings中去找默认配置

     

    django请求生命周期

    (1)过程描述

    第一步:浏览器发起请求
    第二步:WSGI创建socket服务端,接收请求(Httprequest)
    第三步:中间件处理请求
    第四步:url路由,根据当前请求的URL找到视图函数
    第五步:view视图,进行业务处理(ORM处理数据,从数据库取到数据返回给view视图;view视图将数据渲染到template模板;将数据返回)
    第六步:中间件处理响应
    第七步:WSGI返回响应(HttpResponse)
    第八步:浏览器渲染

     中间件用来对请求和响应做一些统一加工和处理的,比如对所有请求中的post请求做一个csrftoken认证,就用到了我们的'django.middleware.csrf.CsrfViewMiddleware',后面视图中能够使用request.session做一个session相关操作,这个request.session的功能就是在这个中间件中加工好的'django.contrib.sessions.middleware.SessionMiddleware',

    自定义中间件: 登录认证、权限认证、频率访问限制,请求数据统计...

    自定义中间件的步骤

    1 在应用文件夹下面创建一个文件夹,名字随便,比如叫做mymiddleware

    2 在mymiddleware文件夹下面创建一个py文件,名称随意,比如叫做middlewares.py

    3 在middlewares.py文件中写上如下内容

    4 在settings.py文件中配置加上自定义的中间件

    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',
        'app01.mymiddleware.middelwares.LoginAuth',
    ]

    # 配置中间件类,告诉django,我写的这个自定义中间件,你帮我使用上,一般都放到最后,不然上面几个中间件的相关功能就没办法使用上了
    'app01.mymiddleware.middlewares.LoginAuth',
    # 如果中间件功能不想用了,就注释它就行了
    # 'app01.mymiddleware.middlewares.LoginAuth'

    这样几步搞定之后,所有的请求都会触发我们的中间件类中的process_request方法。

    登录认证中间件示例

    中间件代码如下

    # 登录认证中间件
    class LoginAuth(MiddlewareMixin):
        # /login/登录请求,应该正常放行,让他能获得login.html页面
        # 白名单、黑名单
        white_list = ['/login/', ]
        def process_request(self,request):
            print('请求来啦!!!')
            # 获取当前请求路径:request.path /home/
            # 如果当前请求的路径在白名单里面,我们不进行登录认证
            if not request.path in self.white_list:
    
                is_login = request.session.get('is_login')  #True
                if not is_login:
                    return redirect('/login/')

    视图代码如下

    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        else:
            uname = request.POST.get('username')
            if uname == 'root':
                request.session['is_login'] = True
    
                return redirect('/home/')  #告诉浏览器向/home/发送get请求获取页面
            else:
                return redirect('/login/')
    
    
    def home(request):
        print('home')
        return render(request, 'home.html')
    
    
    def index(request):
        print('index')
        return render(request, 'index.html')

    中间件的五个方法

    整个中间的执行顺序

     

    方法如下: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)

    针对这个五个方法,我们来看看这5个方法的执行流程。

    1.  process_request

    class Md1(MiddlewareMixin):
    
        def process_request(self,request):
            print('MD1--process_request')
            # 当process_request返回的是None,那么才会继续执行后面的中间件的process_request,如果你是最后一个中间件,
          并且你返回的是None,那么逻辑会继续执行到我们的url路由控制器
    # 但是当process_request里面return的是一个HttpResponse对象,那么后面的中间件的process_request将不再执行,也不会走到url路由控制器 return HttpResponse('中间件md1的逻辑,没有通过!!!!') class Md2(MiddlewareMixin): def process_request(self, request): print('MD2--process_request')

    2 process_response

    class Md1(MiddlewareMixin):
    
        def process_request(self,request):
            print('MD1--process_request')
            # 当process_request返回的是None,那么才会继续执行后面的中间件的process_request,
          如果你是最后一个中间件,并且你返回的是None,那么逻辑会继续执行到我们的url路由控制器
    # 但是当process_request里面return的是一个HttpResponse对象,那么后面的中间件的process_request将不再执行,也不会走到url路由控制器 return HttpResponse('中间件md1的逻辑,没有通过!!!!') def process_response(self, request, response): ''' :param request: 当前请求对象 :param response: 视图函数的响应对象 :return: ''' print('Md1--响应') # print(response) #<HttpResponse status_code=200, "text/html; charset=utf-8"> # 对响应内容做统一处理 # response['xx'] = 'oo' #统一加响应头 # print(response.content) #b'ok' # 注意,如果你写了process_response方法,那么这个方法必须return response return response class Md2(MiddlewareMixin): def process_request(self, request): print('MD2--process_request') def process_response(self, request, response): print('Md2--响应') # if response.content != b'ok': # 如果process_response方法里面return了一个HttpResponse对象,这个对象会覆盖视图返回来的HttpResponse对象 # return HttpResponse('响应不ok!!!') return response

    注意:当中间件1的process_request方法return的是一个HttpResponse对象,那么会执行中间件1的process_response方法,不会去执行中间件2 的方法了

     3 process_view(self, request, view_func, view_args, view_kwargs):

    示例代码

    class Md1(MiddlewareMixin):
    
        def process_request(self,request):
            print('MD1--process_request')
            # return HttpResponse('中间件md1的逻辑,没有通过!!!!')
    
        def process_response(self, request, response):
    
            print('Md1--响应')
            return response
        def process_view(self, request, view_func, view_args, view_kwargs):
            print('md1---view')
    
    class Md2(MiddlewareMixin):
    
        def process_request(self, request):
            print('MD2--process_request')
    
        def process_response(self, request, response):
            print('Md2--响应')
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            '''
    
            :param request:
            :param view_func:   此次请求要执行的视图函数对象
            :param view_args:  要函数的参数
            :param view_kwargs: 要函数的参数
            :return:
            '''
            print('md2---view')
            # print(view_func, view_args, view_kwargs)
            print(view_func.__name__) # home

    4 process_exception(self, request, exception)

    是当试图函数出现错误或者异常时,自动触发执行的方法,能够捕获试图出现的错误,进行一些错误的统一处理

    示例代码

    class Md1(MiddlewareMixin):
    
        def process_request(self,request):
            print('MD1--process_request')
            # return HttpResponse('中间件md1的逻辑,没有通过!!!!')
    
        def process_response(self, request, response):
    
            print('Md1--响应')
            return response
        def process_view(self, request, view_func, view_args, view_kwargs):
            print('md1---view')
    
        def process_exception(self, request, exception):
            print('md1--exception')
    
    class Md2(MiddlewareMixin):
    
        def process_request(self, request):
            print('MD2--process_request')
    
        def process_response(self, request, response):
            print('Md2--响应')
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            '''
    
            :param request:
            :param view_func:   此次请求要执行的视图函数对象
            :param view_args:  要函数的参数
            :param view_kwargs: 要函数的参数
            :return:
            '''
            print('md2---view')
            # print(view_func, view_args, view_kwargs)
            # print(view_func.__name__) # home
    
        def process_exception(self, request, exception):
            
            from django.core.exceptions import PermissionDenied
            # print('>>>>>>', exception, type(exception))
            # if isinstance(exception,PermissionDenied):
            #     return HttpResponse('权限不够!!!!!')
            #>>>>>> 权限不够 <class 'django.core.exceptions.PermissionDenied'>
            # >>>>>> 出错啦!!!
            print('md2--exception')

    视图函数示例

    from django.core.exceptions import PermissionDenied
    
    def home(request):
        print('home')
        # raise Exception('出错啦!!!')
        raise PermissionDenied('权限不够')
        return render(request, 'home.html')

    5 process_template_response(self,request,response)

    代码示例

    from django.shortcuts import render, redirect, HttpResponse
    from django.utils.deprecation import MiddlewareMixin
    
    
    class Md1(MiddlewareMixin):
    
        def process_request(self,request):
            print('MD1--process_request')
            # return HttpResponse('中间件md1的逻辑,没有通过!!!!')
    
        def process_response(self, request, response):
    
            print('Md1--响应')
            return response
        def process_view(self, request, view_func, view_args, view_kwargs):
            print('md1---view')
    
        def process_exception(self, request, exception):
            print('md1--exception')
    
        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')
    
        def process_response(self, request, response):
            print('Md2--响应')
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            print('md2---view')
    
        def process_exception(self, request, exception):
    
            print('md2--exception')
    
        def process_template_response(self, request, response):
            print("MD2 中的process_template_response")
            return response

    视图代码

    def home(request):
        print('home')
        def render():
            print('你好render')
            return HttpResponse('你好response')
    
        ret = HttpResponse('ojbk')
        # 必须给HttpResponse对象封装一个render属性等于一个render函数,才能出发中间件里面的process_template_response方法
        ret.render = render
        return ret
  • 相关阅读:
    Account group in ERP and its mapping relationship with CRM partner group
    错误消息Number not in interval XXX when downloading
    错误消息Form of address 0001 not designated for organization
    Algorithm类介绍(core)
    梯度下降与随机梯度下降
    反思
    绘图: matplotlib核心剖析
    ORB
    SIFT
    Harris角点
  • 原文地址:https://www.cnblogs.com/fdsimin/p/13391757.html
Copyright © 2011-2022 走看看