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
  • 相关阅读:
    Java基础(01)--简介及基础语法
    高数(01)--函数、极限、连续
    未来行业及趋势
    HttpRunner基础使用一:
    web自动化中js操作的操作应用
    django框架学习六:优化views.py文件,使用rest_framework中的APIVew和Response返回
    django框架学习五:djangorestframework中ModelSerializer的关联字段的生成
    django框架学习四:引入djangorestframework中ModelSerializer
    django框架学习三:djangorestframework中序列化器的优化:添加单字段、多字段、自定义函数的校验
    django框架学习三:使用DRF框架,引入序列化器,实现对数据库的增删改查操作
  • 原文地址:https://www.cnblogs.com/fdsimin/p/13391757.html
Copyright © 2011-2022 走看看