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过滤(用户信息验证),缓存。

     

  • 相关阅读:
    Linux驱动入门(三)Led驱动
    Linux驱动入门(二)操作硬件
    mysql表的完整性约束
    数据库操作
    初识数据库
    mysql的安装、启动和基础配置 —— windows版本
    Socket网络编程
    python进阶之多线程(简单介绍协程)
    python进阶多进程(进程池,进程间通信)
    python基础之异常处理
  • 原文地址:https://www.cnblogs.com/Ting-light/p/9842771.html
Copyright © 2011-2022 走看看