ySJ
|
2.0/chapter16/#588 |
2010-04-23 16:45:40
|
这些继承框架(CSRF、身份验证系统等等)通过提供 <emphasis>中间件</emphasis> 来实现其奇妙的功能。中间件是在请求之前/后执行的可以修改请求和响应的代码,它扩展了框架。
|
|
ySJ
|
2.0/chapter16/#589 |
2010-04-23 16:46:02
|
在下一章,我们将介绍Django的中间件并解释怎样写出自己的中间件。
|
|
ySJ
|
2.0/chapter16/#592 |
2010-04-23 16:46:25
|
谨奉
|
|
ySJ
|
2.0/chapter16/#591 |
2010-04-23 16:47:14
|
受<reference name="GNU Free Document License" refuri="/license/">GNU Free Document License</reference>约束。
|
|
ySJ
|
2.0/chapter17/#11 |
2010-04-26 09:20:12
|
如果你是顺着这本书读下来的话,你应该已经多次见到“中间件”了:
|
|
ySJ
|
2.0/chapter17/#13 |
2010-04-26 09:23:03
|
第14章中所有的session和user工具都籍由一小簇中间件实现(例如,由中间件设定view中可见的 <literal>request.session</literal> 和 <literal>request.user</literal> )。
|
|
ySJ
|
2.0/chapter17/#15 |
2010-04-26 09:59:24
|
第15章讨论的站点范围cache实际上也是由一个中间件实现,一旦该中间件发现与view相应的response已在缓存中,就不再调用对应的view函数。
|
|
ySJ
|
2.0/chapter17/#17 |
2010-04-26 10:04:53
|
第16章所介绍的 <literal>flatpages</literal> , <literal>redirects</literal> , 和 <literal>csrf</literal> 等应用也都是通过中间件组件来完成其魔法般的功能。
|
|
ySJ
|
2.0/chapter17/#25 |
2010-04-26 10:51:49
|
流量很大的站点通常需要将Django部署在平衡负载的代理(参见第12章)后面。
|
|
ySJ
|
2.0/chapter17/#51 |
2010-04-26 11:15:10
|
Django项目的安装并不强制要求任何中间件,如果你愿意, <literal>MIDDLEWARE_CLASSES</literal> 可以为空。但是我们建议你激活<literal>CommonMiddleware</literal>,这点我们会马上解释。
|
|
ySJ
|
2.0/chapter17/#55 |
2010-04-26 11:19:37
|
也就是说,Django将 <literal>MIDDLEWARE_CLASSES</literal> 视为view函数外层的顺序包装:
|
|
ySJ
|
2.0/chapter17/#62 |
2010-04-26 11:22:29
|
Initializer:
|
|
ySJ
|
2.0/chapter17/#63 |
2010-04-26 11:22:38
|
__init__(self)
|
|
ySJ
|
2.0/chapter17/#76 |
2010-04-26 12:46:11
|
Request预处理函数:
|
|
ySJ
|
2.0/chapter17/#87 |
2010-04-26 12:48:40
|
Django将立即返回该 <literal>HttpResponse</literal>。
|
|
ySJ
|
2.0/chapter17/#89 |
2010-04-26 12:49:30
|
View预处理函数:
|
|
ySJ
|
2.0/chapter17/#92 |
2010-04-26 12:50:40
|
这个方法的调用时机是在Django执行完request预处理函数并确定待执行的view之后,但在view函数实际执行之前。
|
|
ySJ
|
2.0/chapter17/#94 |
2010-04-26 12:51:18
|
表17-1列出了传入到这个View预处理函数的参数。
|
|
ySJ
|
2.0/chapter17/#97 |
2010-04-26 12:54:46
|
表 17-1.
|
|
ySJ
|
2.0/chapter17/#119 |
2010-04-26 13:00:10
|
被传入view的关键字参数字典.
|
|
ySJ
|
2.0/chapter17/#121 |
2010-04-26 13:06:39
|
跟<literal>process_request()</literal>一样,<literal>process_view()</literal>应该返回一个<literal>HttpResponse</literal>对象或者返回<literal>None</literal>。
|
|
ySJ
|
2.0/chapter17/#128 |
2010-04-26 13:42:36
|
Response后处理函数:
|
|
ySJ
|
2.0/chapter17/#135 |
2010-04-26 13:48:34
|
这个方法的参数相当直观:
|
|
ySJ
|
2.0/chapter17/#138 |
2010-04-26 13:52:49
|
不像可能返回 <literal>None</literal>和<literal>process_response()</literal>的request和view预处理函数,
|
|
ySJ
|
2.0/chapter17/#139 |
2010-04-26 13:53:49
|
<emphasis>必须</emphasis> 返回 <literal>HttpResponse</literal> 对象。
|
|
ySJ
|
2.0/chapter17/#142 |
2010-04-26 13:54:44
|
Exception后处理函数:
|
|
ySJ
|
2.0/chapter17/#154 |
2010-04-26 14:10:03
|
如果返回 <literal>HttpResponse</literal> 对象, Django 将使用该response对象,而不采用框架内置的异常处理机制。
|
|
ySJ
|
2.0/chapter17/#161 |
2010-04-26 14:10:39
|
在Djangos wiki上也可以找到大量的社区贡献的中间件范例:
|
|
ySJ
|
2.0/chapter17/#170 |
2010-04-26 14:14:15
|
中间件类:
|
|
ySJ
|
2.0/chapter17/#173 |
2010-04-26 14:14:37
|
这个中间件激活认证支持功能。
|
|
ySJ
|
2.0/chapter17/#176 |
2010-04-26 14:15:04
|
完整的细节请参见第14章。
|
|
ySJ
|
2.0/chapter17/#185 |
2010-04-26 14:16:37
|
<emphasis>禁止对``DISALLOWED_USER_AGENTS`` 列表中设置的user agent访问</emphasis> :一旦提供,这一列表应当由已编译的正则表达式对象组成,这些对象用于匹配传入的request请求头中的user-agent域。
|
|
ySJ
|
2.0/chapter17/#189 |
2010-04-26 14:18:23
|
请注意 <literal>import re</literal> ,因为 <literal>DISALLOWED_USER_AGENTS</literal> 要求其值为已编译的正则表达式(也就是 <literal>re.compile()</literal> 的返回值)。设置文件是标准Python格式,所有你完全可以使用<literal>import</literal>语句。
|
|
ySJ
|
2.0/chapter17/#191 |
2010-04-26 14:39:07
|
<emphasis>依据 ``APPEND_SLASH`` 和 ``PREPEND_WWW`` 的设置执行URL重写</emphasis> :如果 <literal>APPEND_SLASH</literal> 为 <literal>True</literal> , 那些尾部没有斜杠的URL将被重定向到添加了斜杠的相应URL,除非path的最末组成部分包含其他部分。
|
|
ySJ
|
2.0/chapter17/#194 |
2010-04-26 14:39:53
|
如果 <literal>PREPEND_WWW</literal> 为 True , 那些缺少先导www.的
|
|
ySJ
|
2.0/chapter17/#195 |
2010-04-26 14:40:03
|
URLs将会被重定向到含有先导www.的相应URL上。
|
|
ySJ
|
2.0/chapter17/#199 |
2010-04-26 14:49:53
|
技术上来说,URL <literal>example.com/bar</literal> 与 <literal>example.com/bar/</literal> 及 <literal>www.example.com/bar/</literal> 都互不相同。搜索引擎索引器会把它们区别对待,这样会影响站点在搜索引擎上的排名,所以最好使用正常的URL。
|
|
ySJ
|
2.0/chapter17/#202 |
2010-04-26 14:54:24
|
如果 <literal>USE_ETAGS</literal> 为 <literal>True</literal> ,Django针对每个请求以MD5算法处理页面内容,从而得到Etag, 在此基础上,Django将在适当情形下处理并返回 <literal>Not Modified</literal> 响应。
|
|
ySJ
|
2.0/chapter17/#204 |
2010-04-26 14:55:56
|
请注意,还有一个条件化的 <literal>GET</literal> 中间件, 处理Etags并且还有些别的功能,下面马上就会提及。
|
|
ySJ
|
2.0/chapter17/#212 |
2010-04-26 14:59:59
|
这将极大地减少Web服务器消耗的带宽。
|
|
ySJ
|
2.0/chapter17/#215 |
2010-04-26 15:01:32
|
比起带宽,人们一般更青睐速度,但是如果你的情形正好相反,尽可启用这个中间件。
|
|
ySJ
|
2.0/chapter17/#224 |
2010-04-26 15:05:28
|
对 <literal>ETag</literal> 的支持依赖于 <literal>USE_ETAGS</literal> 配置及事先在response头中设置 <literal>ETag</literal> 域。
|
|
ySJ
|
2.0/chapter17/#225 |
2010-04-26 15:06:53
|
稍前所讨论的通用中间件可用于设置response中的ETag域。
|
|
ySJ
|
2.0/chapter17/#227 |
2010-04-26 15:12:25
|
此外,它也将删除所有针对<literal>HEAD</literal>请求的响应内容,并且为所有请求的响应头中设置 <literal>Date</literal> 和 <literal>Content-Length</literal> 域。
|
|
ySJ
|
2.0/chapter17/#227 |
2010-04-26 15:12:31
|
此外,它也将删除所有针对<literal>HEAD</literal>请求的响应内容,并且为所有请求的响应头设置 <literal>Date</literal> 和 <literal>Content-Length</literal> 域。
|
|
ySJ
|
2.0/chapter17/#234 |
2010-04-26 15:13:19
|
这是我们在“什么是中间件”这一节中所举的例子。
|
|
ySJ
|
2.0/chapter17/#235 |
2010-04-26 15:14:11
|
前面一段。
|
|
ySJ
|
2.0/chapter17/#236 |
2010-04-26 15:14:55
|
在<literal>request.META['HTTP_X_FORWARDED_FOR']</literal>存在的前提下,它根据其值来设置<literal>request.META['REMOTE_ADDR']</literal>。
|
|
ySJ
|
2.0/chapter17/#237 |
2010-04-26 15:16:30
|
如果站点位于某个反向代理之后,那么每个request的REMOTE_ADDR都被指向127.0.0.1,在这种情况下,这一功能将非常有用。
|
|
ySJ
|
2.0/chapter17/#239 |
2010-04-26 15:16:47
|
危险!
|
|