Django MiddleWare 排序的实用规则?

发布于 2024-10-10 19:35:28 字数 2454 浏览 2 评论 0原文

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

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

您能否建议对内置中间件类进行一些正确的排序(假设我们启用所有这些类),并且最重要的是解释为什么一个类在其他类之前/之后?

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

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

(我将向此列表添加建议以收集所有建议在一个地方)

The official documentation is a bit messy: 'before' & 'after' are used for ordering MiddleWare in a tuple, but in some places 'before'&'after' refers to request-response phases. Also, 'should be first/last' are mixed and it's not clear which one to use as 'first'.

I do understand the difference.. however it seems to complicated for a newbie in Django.

Can you suggest some correct ordering for builtin MiddleWare classes (assuming we enable all of them) and — most importantly — explain WHY one goes before/after other ones?

here's the list, with the info from docs I managed to find:

  1. UpdateCacheMiddleware
    • Before those that modify 'Vary:' SessionMiddleware, GZipMiddleware, LocaleMiddleware
  2. GZipMiddleware
    • Before any MW that may change or use the response body
    • After UpdateCacheMiddleware: Modifies 'Vary:'
  3. ConditionalGetMiddleware
    • Before CommonMiddleware: uses its 'Etag:' header when USE_ETAGS=True
  4. SessionMiddleware
    • After UpdateCacheMiddleware: Modifies 'Vary:'
    • Before TransactionMiddleware: we don't need transactions here
  5. LocaleMiddleware, One of the topmost, after SessionMiddleware, CacheMiddleware
    • After UpdateCacheMiddleware: Modifies 'Vary:'
    • After SessionMiddleware: uses session data
  6. CommonMiddleware
    • Before any MW that may change the response (it calculates ETags)
    • After GZipMiddleware so it won't calculate an E-Tag on gzipped contents
    • Close to the top: it redirects when APPEND_SLASH or PREPEND_WWW
  7. CsrfViewMiddleware
    • Before any view middleware that assumes that CSRF attacks have been dealt with
  8. AuthenticationMiddleware
    • After SessionMiddleware: uses session storage
  9. MessageMiddleware
    • After SessionMiddleware: can use Session-based storage
  10. XViewMiddleware
  11. TransactionMiddleware
    • After MWs that use DB: SessionMiddleware (configurable to use DB)
    • All *CacheMiddleWare is not affected (as an exception: uses own DB cursor)
  12. FetchFromCacheMiddleware
    • After those those that modify 'Vary:' if uses them to pick a value for cache hash-key
    • After AuthenticationMiddleware so it's possible to use CACHE_MIDDLEWARE_ANONYMOUS_ONLY
  13. FlatpageFallbackMiddleware
    • Bottom: last resort
    • Uses DB, however, is not a problem for TransactionMiddleware (yes?)
  14. RedirectFallbackMiddleware
    • Bottom: last resort
    • Uses DB, however, is not a problem for TransactionMiddleware (yes?)

(I will add suggestions to this list to collect all of them in one place)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自此以后,行同陌路 2024-10-17 19:35:28

最困难的部分是在设置顺序时必须同时考虑两个方向。我想说这是设计中的缺陷,我个人会选择单独的 requestresponse 中间件顺序(这样你就不需要像 FetchFromCacheMiddleware< /code> 和 UpdateCacheMiddleware)。

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

无论哪种方式,其全部思想都是您的请求按自上而下的顺序传递 process_requestprocess_view 的中间件列表。它以相反的顺序通过 process_responseprocess_exception 传递您的响应。

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

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

The most difficult part is that you have to consider both directions at the same time when setting the order. I would say that's a flaw in the design and I personally would opt for a separate request and response middleware order (so you wouldn't need hacks like FetchFromCacheMiddleware and UpdateCacheMiddleware).

But... alas, it's this way right now.

Either way, the idea of it all is that your request passes through the list of middlewares in top-down order for process_request and process_view. And it passes your response through process_response and process_exception in reverse order.

With UpdateCacheMiddleware this means that any middleware that changes the Vary headers in the HTTP request should come before it. If you change the order here than it would be possible for some user to get a cached page for some other user.

How can you find out if the Vary header is changed by a middleware? You can either hope that there are docs available, or simply look at the source. It's usually quite obvious :)

冷弦 2024-10-17 19:35:28

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

One tip that can save your hair is to put TransactionMiddleware in such place on the list, in which it isn't able to rollback changes commited to the database by other middlewares, which changes should be commited no matter if view raised an exception or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文