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

    Django中Middleware中间件

    1 Middleware中间件概述

    	django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法。实际上当我们想在发起请求到服务器views处理函数,我们想对请求做一些提前处理,此时中间件就上场了。
    
    django在settings模块中,有一个MIDDLEWARE_CLASSES变量,其中每一个元素就是一个中间件。
    在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',
        'django.middleware.DataConvert',
        '自定义中间件添加位置'
    ]
    
    常见的middleware组件:
    1. Sessions   	
    2. Authentication 	
    3. CSRF Protection 
    4. GZipping Content
    

    2 Middleware处理功能

    在Djano中,中间件承担作用   Resquest---->Middleware ---->View----->Response
    比如如果想实现接入安全验证,middleware是比较好的选择,是连接request与view的桥梁
    Django中支持的中间件可以实现如下方法:
    
    	方法名称			执行周期
    	process_request		接受到request之后,但在确定View之前
    	process_view		确定view之后,但真正执行view之前
    	process_response	执行view之后
    	process_exception	view抛出异常之后
    	
    详解: 每个请求都是先通过中间件process_request函数,这个函数返回None或者HttpResponse对象,返回前者继续处理其他中间件,返回HttpResponse,处理终止返回网页内容.每个中间件都是按照顺序依次进入处理程序.
    

    3 自定义中间件Middleware

    	我们网站放在服务器正式运行之后,DEBUG改为False,这样更加安全,但有时候发生错误不能显示错误详情页面,普通用户看到的是友好的报错信息,管理员看到的是错误详情,以便于修复BUG,为达到两者效果,利用middleware就能做到.下面我们看下我们定义的Middleware:
    import sys
    from django.views.debug import technical_500_response
    from django.conf import settings
    
    class UserBasedExceptionMiddleware(object):
       def process_exception(self, request, exception):
           if request.user.is_superuser or request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
               return technical_500_response(request, *sys.exc_info())
               
    	在给大家展示一个有用的例子,我们都知道浏览器发送数据仅支持GET和POST两种请求方式,那我们是怎么实现PUT,DELETE,OPTIONS请求的功能的呢?  下面我们将展示采用中间件将request中的请求信息进行转化的方法:
    
    PUT/DELETE/OPTIONS方法的转换中间件:
    
    import json
    from django.utils.deprecation import MiddlewareMixin
    from django.http.multipartparser import MultiPartParser
    
    class MethodConvertMiddleware(MiddlewareMixin):
        #创建请求处理函数
        def process_request(self,request):
            method = request.method
            #判断请求请求头信息中content-type是否含有application/json
                
            if 'application/json' in request.META['CONTENT_TYPE']:
                #json格式转Python字典
                data = json.loads(request.body.decode()
            #判断请求请求头信息中content-type是否含有mutipart/form-data
            
            elif 'mutipart/form-data' in request.META['CONTENT_TYPE']:
                #解析器解析出data与文件
                data,files = MultiPartParser(request.META,request,request.upload_handlers).parse()
            else:
                #这里不支持application/x-www-form-urlencoded,其余返回{}
                data = {}
                files = None
            #前段讲请求方式放在HTTP_X_METHOD
            if 'HTTP_X_METHOD' in request.META:
                method = request.META['HTTP_X_METHOD'].upper()
                #例如设定method = 'PUT'
                setattr(request,'method',method)
            if files:
                #files存在 request.PUT_FILES = files  数据data也设置给PUT,这样就转换过来了
                setattr(request,'{method}_FILES'.format(method=method),files)
            setattr(request,method,data)
            #中间件进入下一个处理程序
            return None
    注:1  中间件没有添加异常处理程序,可自行添加.
       2  中间件只针对两种常见数据类型格式application/json 与 application/form-data.
  • 相关阅读:
    Redis缓存穿透和雪崩
    Redis主从复制
    Redis发布订阅
    IO多路复用
    Synchronized解读
    日志导致jvm内存溢出相关问题
    tomcat及springboot实现Filter、Servlet、Listener
    MySQL主从复制针对trigger的特殊处理
    二、变量/常量/数据类型
    Ubuntu21.04 / Linux Mint20.2 安装 TradingView分析软件
  • 原文地址:https://www.cnblogs.com/why957/p/9073680.html
Copyright © 2011-2022 走看看