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

     django 1.11

    中间件的制造工厂是一个方法接收get_response 作为入参返回一个中间件。一个中间件是一个可调用的对象,接收一个request返回一个response,就像view.

    middleware也可以写作一个方法

    def simple_middleware(get_response):

      def middleware(request):

        response=get_response(request)

        return response

      return middleware 

    或者写作一个类class

    class SimpleMiddleware(object):

      def __init__(self,get_response):

        self.get_response=get_response

      def __call__(self,request):

        response=self.get_response(request)

        return response

    get_response由django提供,它可能是一个view(如果这个middleware排在最后)也可能是链条中的下一个middleware。当前的中间件不需要知道它具体是什么,它仅仅代表了生成的结果

    django只需要get_response一个参数来初始化中间件,所以你定义__init__()时不能添加其他的参数。

    __call__()方法每次请求都会被调用一次,__init__()方法仅在web服务器开启的时候被调用一次。

    当middleware不应该被启用时,middleware的__init__方法会抛出MiddlewareNotUsed,然后django会将此middleware从中间价进程中移除,并且会产生一条debug级别的日志。

    在MIDDLEWARE列表中的的中间件的顺序会影响他们依赖的中间件。比如AuthenticationMiddleware在session中存储了已认证的用户,所以它必须在SessionMiddleware之后运行

    在request阶段,请求先从MIDDLEWARE列表中由上到下穿过,然后到达view,然后response将由middleware中由下到上穿过返回.

    如果有一个middleware在request阶段没有调用get_response,直接返回response,那么剩下的middleware(包括view)也就不会见到request或response了。这个response会倒序穿过request穿过的middleware.

     

    class形式的middleware通常包括一下处理方法:

    process_request(request)

    process_reponse(request,response)

    process_view(request,view_func,view_args,view_kwargs) 在调用view之前被调用

    view_func :一个真正的方法对象,而不是方法名字的字符串

    view_args和view_kwargs分别是view_func的位置入参和关键字入参,他们都不需要传入request

    它返回 None和HttpResponse中的一个,如果是none则继续调用下一个middleware的process_view,如果是HttpResponse则不会再调用view而是调用response middleeware来处理response后直接返回结果

    如果通过middleware在调用view之前访问了request.POST,将会阻止任何view在运行过程中可能修改request的上传器的行为

    CscrViewMiddleware可以看作一个异常处理器,它提供csrf_exempt()和csrf_protect()装饰器可以让view明确控制CSRF应该确认的点

    process_exception(request,exception) 当view抛出异常时 被调用

    它返回None和HttpResponse中的一个,如果返回Httpresponse,则reponse middleware继续被应用于该response,否则由默认的异常处理来处理它。

    response经过中间件的顺序是由下向上,process_exception被调用的顺序也是由下向上。如果一个exception middleware返回一个response,那么该中间件之上的response中间件就不会被调用了。

    process_template_response(request,response)在view刚被调用完后被调用,执行顺序同response

    request: HttpRequest对象。

    response:由view或middleware返回的TemplateResponse对象。如果一个response实例有render()方法,就表明它是一个TemplateResponse对象。

    它必须返回一个执行了render方法的response。 在该方法中可以改变 传入的response的response.template_name 和response.context_data 或者创建一个新的Tempalteresponse返回

    response不需要明确的被渲染,一旦template response middleware被调用,response会自动被选染。

     TemplateResponse保留了view计算出reponse的上下文,最后输出response是直到它被需要时才在reponse process中计算完成的

     处理  流式reponse

    与HttpResponse不同,StreamingHttpResponse没有属性content.当middleware需要使用content时,必须判断response是否为streaming response 来响应的调整他们的行为。

    if reponse.streaming:

      reponse.streaming_content=wrap_streaming_content(response.streaming_content)

    else:

      reponse.content=alter_content(reponse.content)

    应该将streaming reponse 预估为较大的,内存无法承担的对象,应使用generator来逐步使用,如下:

    def wrap_streaming_content(content):

      for chunk in content:
        yield alter_content(chunk)

     

    处理异常

    django会自动将view或middleware产生的异常转化成对应的 http错误 响应码页面

    明确的异常映射成4xx错误码,未知异常映射成500错误码

    这种映射发生在每个middleware之前和之后,这个每个middleware都可以确定通过get_reponse可以收到http reponse,而不用使用try/except来处理get_reponse的返回值,打比方说后面的middleware中抛出一个Http404的异常,当前的middleware不会接收到这个异常,而是获取到一个Httpresponse对象,及一个404的status_code。

     

     缓存中间件

    如果开启了缓存中间键,它会作用于url映射的每个页面

    规范的设置方式是 将UpdateCacheMiddleware作为第一个中间键,FetchFromCacheMiddleware作为最后一个,以便request在最后一步经过FetchFromCacheMiddleware来通过缓存返回response ,response在最后一步经过UpdateCacheMiddleware来更新一个可缓存的response的缓存:

    MIDDLEWARE=[

    'django.middleware.cache.UpdateCacheMiddleware',

    ...

    'django.middleware.cache.FetchFromCacheMiddleware'

    ]

    只有请求方式为get或head且状态码为200的内容会被缓存

    页面缓存的保存秒数 由response响应头"Cache-Control"的"max-age"属性值决定,如果没有找到该属性则根据settings.py中的CACHE_MIDDLEWARE_SECONDS的值来确定

    这个中间件期望请求的响应头与get类型请求的响应头几乎一致

    当发生攻击时,process_request将会浅复制一个原始的response对象,返回。

    页面将会根据请求头在response's "vary" header中列出的内容来缓存

    这个中间键也可以设置reponse响应头的ETag,Last-Modified,Expires和Cache-Control值

    使用时,在view中from django.views.decorators.cache import cache_page ,然后在需要缓存的函数页面上加上 @cache_page(seconds)即可,seconds表示缓存的有效秒数。

     

    在settings.py中的CACHES设置 缓存的数据应该保存在哪里,数据库,文件系统或直接保存到内存。

    可用的值有:

    Memcached

     django默认支持的快速,高效的缓存 key-value数据库,完全基于内存的缓存服务,它只是提供了一个快速的删除,检索,添加 缓存里数据的接口。

    安装完Memcached 后需要安装相关依赖 ,常用的有python-memcached和pylibmc . 

    在django中起用Memcached 作为缓存,将backend设置为django.core.cache.backends.memcached.MemcachedCache或者

    django.core.cache.backends.memcached.PlLibMCCache

    location设置为‘ip:port',或者 unix:path ,path为Memcached Unix socket文件的路径(例 'unix:/tmp/memcached.sock') ,例

    CACHES={

      'default':{

        'BACKEND':'django.core.cache.backends.memcached.MemcachedCache',

        'LOCATION':'127.0.0.1:11211',

        }

      }

    当backends使用pylibmc时,LOCATION应设置为’/tmp/memcached.sock'

    Memcached有一个比较好的特性是可以在多个服务器上共享缓存。这意味着可以在不同的服务器上各自运行一个Memcache,不需要复制缓存值,应用工程可以把这个集群看作单个的缓存服务器,启用这种特性需要将所有的地址添加进LOCATION,可以以list或分号,逗号分隔的字符串表示。如:

    CACHES={

      ‘default':{

        'BACKEDN':'django.core.cache.backends.memcached.MemcachedCache',

        'LOCATION':[

              '172.19.26.240:11211',

              '172.19.26.142:11212',

              '172.19.26.244:11213',

              ]

          }

        }

    Memcached是一个基于缓存的数据库,所以如果服务器宕机了,存储于其中的数据就会丢失。

    中间件的应用场景,一般用来做IP限制(放在中间件的列表中,阻止某些IP访问;),URL过滤(用户信息验证),缓存。

     

  • 相关阅读:
    UVa532 Dungeon Master 三维迷宫
    6.4.2 走迷宫
    UVA 439 Knight Moves
    UVa784 Maze Exploration
    UVa657 The die is cast
    UVa572 Oil Deposits DFS求连通块
    UVa10562 Undraw the Trees
    UVa839 Not so Mobile
    327
    UVa699 The Falling Leaves
  • 原文地址:https://www.cnblogs.com/Ting-light/p/9842771.html
Copyright © 2011-2022 走看看