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

    中间件定义:

      中间件是一个、一个的管道,如果相对任何所有的通过Django的请求进行管理都需要自定义中间件

      中间件可以对进来的请求和出去的请求进行控制

      中间件是一类。

    看下面的代码在settings里中间件的类:

    MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    当有请求过来的时候,默认从上倒下执行!然后在返回的时候从下面在返回回去,如下图:

    2、自定义中间件

    中间件中可以定义四个方法,分别是:

    • process_request(self,request)
    • process_view(self, request, callback, callback_args, callback_kwargs)
    • process_exception(self, request, exception)
    • process_response(self, request, response)

    process_exception 这个方法只有在出现错误的时候才会触发

    先写一个自定义中间件,然后在看他的原理和源码:

    2.1、自定义中间件

     
    class Testmiddle(object):
        def process_request(self,request):
            print 'Testmiddle process_request'
        def process_view(self, request, callback, callback_args, callback_kwargs):
            print 'Testmiddle process_view'
        def process_exception(self, request, exception):
            pass
        def process_response(self, request, response):
            print 'Testmiddle process_response'
            return response
        
    class Nextmiddle(object):
        def process_request(self,request):
            print 'Nextmiddle process_request'
        def process_view(self, request, callback, callback_args, callback_kwargs):
            print 'Nextmiddle process_view'
        def process_exception(self, request, exception):
            pass
        def process_response(self, request, response):
            print 'Nextmiddle process_response'
            return response
     

    2.2、注册中间件

    MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
       # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'middleware.middle.Testmiddle',
        'middleware.middle.Nextmiddle',
    ]

    2.3、测试使用url和views

    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/$', views.index),
    
    ]
    def index(request):
        print 'This app01 Views.index'
        return HttpResponse('OK')

    2.4、查看输出结果:

    '''
    Testmiddle process_request
    Nextmiddle process_request
    Testmiddle process_view
    Nextmiddle process_view
    This app01 Views.index
    Nextmiddle process_response
    Testmiddle process_response
    '''

    从输出结果可以看出:

    他是先执行Testmiddle 的request 方法又执行了Nextmiddle的 process_request方法。。。。

    2.5、原理:

    当请求进来了到达中间件

    去settings里面找到MIDDLEWARE_CLASSES,MIDDLEWARE_CLASSES是一个元组

    有4个列表:

    process_request_lsit = []
    process_view_list = []
    process_response_list = []
    然后他循环MIDDLEWARE_CLASSES这个类:
    for 类 in MIDDLEWARE_CLASSES:
      obj = 类()
      if obj里有process_request方法:
        process_request_lsit.append(obj.process_request)

    然后循环后后执行:

    for i in process_request_list:
      i() #加括号执行方法
    
    for i in process_view_list:
        i() 
        ............

    3、中间件的流程梳理

    首先看下自定义的中间件中的process_response方法他是有返回值的其他的是没有返回值的。这个return response是什么呢?

    这个response就是咱们自定义的views.index返回的结果!

        def process_response(self, request, response):
            print 'Testmiddle process_response'
            return response

    如果在其他的没有返回值得,仅有process_response有返回值得话他的请求流程是这样的:

    但是如果在process_request或者process_view又返回值得话那么流程就完全不一样了!

    举例:如果有m1和m2两个中间件,如果我在m1中的request方法中设置了,如果访问为1.1.1.1那么返回要一个404,那么他的访问流程是这样的:

    process_exception  什么时候触发呢?咱们定义的views.index出错的时候他就会捕捉到然后执行咱们定义的process_exception方法如下图:

    Django缓存

    由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者Redis中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。

    举个例子来说:如果访问量比较大的时候,有很多相同的操作比如:有时候请求的数据比如访问同一条数据,或者同一个页面的时候,其实是没必要的。

    Django支持,mysql,Redis、Memecache、文件的方式做缓存,并且可以设置超时时间。

    settings配置:

    CACHES = {
        'default': {
            #定义已文件的方式进行cache
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
            #cache文件的存放路径
            'LOCATION': os.path.join(BASE_DIR, 'cache'),
            #超时时间为600妙
            'TIMEOUT': 600,
            'OPTIONS': {
                'MAX_ENTRIES': 1000
            }
        }
    }

    给请求应用,就是使用装饰器

    from django.views.decorators.cache import cache_page
    
    #这里设置的是 60秒 * 15 ,15分钟之后
    @cache_page(60 * 15)
    def cache_page(request):
        current = str(time.time())
        return HttpResponse(current)
    有一种能力,是持续不断的努力
  • 相关阅读:
    常用256安全色
    PHP获取中英文混合字符串的字数
    windows 2012 443端口无法访问解决随记!
    SQL提取时间段内数据
    正则表达式匹配
    PclZip library能够压缩与解压缩Zip格式
    安装IIS或证书上服务提示安装程序无法复制文件 ftpsvc2.dl的解决办法
    tomcat
    版本控制gitlab
    rsync
  • 原文地址:https://www.cnblogs.com/shaojiafeng/p/7805749.html
Copyright © 2011-2022 走看看