【问题标题】:Practical rules for Django MiddleWare ordering?Django MiddleWare 订购的实用规则?
【发布时间】:2011-06-05 15:54:15
【问题描述】:

官方文档有点乱:'before' & 'after' 用于在元组中排序 MiddleWare,但在某些地方 'before'&'after' 指的是请求-响应阶段。此外,“应该是第一个/最后一个”是混合的,不清楚哪个用作“第一个”。

我确实理解其中的区别。但是对于 Django 的新手来说,这似乎很复杂。

您能否为内置的 MiddleWare 类推荐一些正确的顺序(假设我们启用了所有这些类)并且——最重要的是——解释为什么一个在其他类之前/之后?

这是列表,其中包含我设法找到的文档中的信息:

  1. UpdateCacheMiddleware
    • 在那些修改'Vary:'之前SessionMiddlewareGZipMiddlewareLocaleMiddleware
  2. GZipMiddleware
    • 在任何可能更改或使用响应正文的 MW 之前
    • UpdateCacheMiddleware 之后:修改“Vary:”
  3. ConditionalGetMiddleware
    • CommonMiddleware 之前:在USE_ETAGS=True 时使用其'Etag:' 标头
  4. SessionMiddleware
    • UpdateCacheMiddleware 之后:修改“Vary:”
    • TransactionMiddleware 之前:我们这里不需要交易
  5. LocaleMiddleware,最顶层之一,在 SessionMiddleware、CacheMiddleware 之后
    • UpdateCacheMiddleware 之后:修改“Vary:”
    • SessionMiddleware 之后:使用会话数据
  6. CommonMiddleware
    • 在任何可能改变响应的 MW 之前(它计算 ETag)
    • GZipMiddleware 之后,它不会计算压缩内容的电子标签
    • 接近顶部:当APPEND_SLASHPREPEND_WWW时重定向
  7. CsrfViewMiddleware
    • 在任何假定 CSRF 攻击已被处理的视图中间件之前
  8. AuthenticationMiddleware
    • SessionMiddleware 之后:使用会话存储
  9. MessageMiddleware
    • SessionMiddleware之后:可以使用基于Session的存储
  10. XViewMiddleware
  11. TransactionMiddleware
    • 在使用 DB 的 MW 之后:SessionMiddleware(可配置为使用 DB)
    • 所有*CacheMiddleWare 不受影响(例外:使用自己的数据库游标)
  12. FetchFromCacheMiddleware
    • 在那些修改 'Vary:' 之后,如果使用它们来选择缓存哈希键的值
    • AuthenticationMiddleware 之后,所以可以使用CACHE_MIDDLEWARE_ANONYMOUS_ONLY
  13. FlatpageFallbackMiddleware
    • 底部:最后的手段
    • 不过,使用 DB 对 TransactionMiddleware 来说不是问题(是吗?)
  14. RedirectFallbackMiddleware
    • 底部:最后的手段
    • 不过,使用 DB 对 TransactionMiddleware 来说不是问题(是吗?)

(我会将建议添加到此列表中,以便将所有建议收集到一个地方)

【问题讨论】:

  • MessageMiddleware 需要在 SessionMiddleWare 之后,因为消息框架可以使用基于会话的后端来存储消息。
  • 这应该是一个社区问题,因为不可能有一个人有一个正确的答案:) 但是,我没有看到任何复选框
  • 我同意该术语令人困惑。也许“内部”和“外部”会更合适。那些靠近 settings.MIDDLEWARE_CLASSES 开头的列表是“外部;”列在最后的那些是“内部”。这与 django 文档中的图形描述相匹配,并且还表示中间件在执行时可以设置一个环境后续中间件将在其中运行。
  • 为什么这个问题没有数百个星星和点赞,我永远不会知道!谢谢!
  • Django 在两年内发生了很大的变化,有没有指向相同但更最近资源的指针?谢谢,+1ed。

标签: django django-middleware


【解决方案1】:

最困难的部分是你在设置顺序时必须同时考虑两个方向。我会说这是设计中的一个缺陷,我个人会选择单独的 requestresponse 中间件订单(这样你就不需要像 FetchFromCacheMiddlewareUpdateCacheMiddleware 这样的黑客)。

但是……唉,现在就是这样。

无论哪种方式,这一切的想法是您的请求以自上而下的顺序通过中间件列表,用于process_requestprocess_view。它会以相反的顺序通过process_responseprocess_exception 传递您的回复。

对于UpdateCacheMiddleware,这意味着任何更改HTTP 请求中Vary 标头的中间件都应该在它之前。如果您在此处更改顺序,则某些用户可能会为其他用户获取缓存页面。

如何确定Vary 标头是否被中间件更改?您可以希望有可用的文档,或者只是查看源代码。这通常很明显:)

【讨论】:

【解决方案2】:

可以节省您的头发的一个技巧是将 TransactionMiddleware 放在列表中的这样一个位置,其中它无法回滚其他中间件提交给数据库的更改,无论视图是否引发了这些更改都应该提交例外与否。

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 2017-09-14
    • 2014-11-16
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多