我在很多地方都看到,使用线程本地存储在 Django 应用程序中存储任何数据都不是一个好习惯。 但这是我可以存储我的请求对象的唯一方法。我需要存储它,因为我的应用程序结构复杂。而且我不能继续在每个函数调用或类初始化时传递请求对象。
我需要将我的请求对象中的 cookie 和 header 传递给我在应用程序的不同位置进行的一些 api 调用。
所以我使用的是中间件,如引用文献中所述。 而且,这就是请求的存储方式
from threading import local
_thread_locals = local()
_thread_locals.request = request
而且,这就是获取数据的方式:
getattr(_thread_locals, "request", None)
那么数据是否存储在特定请求的本地线程中?或者如果同时发生另一个请求,它们是否使用相同的数据?(这肯定不是我想要的)
或者有什么新方法可以解决这个老问题(全局存储请求对象)
注意:我还在我的 Django 应用程序中的位置使用 async
(如果这很重要的话)。
最佳答案
是的,在 Django 中使用线程本地存储是安全的。
Django 使用一个线程来处理每个请求。 Django 本身也使用线程本地数据,例如 storing the currently activated locale .而像 Gunicorn 这样的应用服务器和 uwsgi可以配置为使用多个线程,每个请求仍将由单个线程处理。
但是,there have been conflicting opinions关于使用 thread-locals 是否是一个优雅且设计良好的解决方案。反对使用线程局部变量的原因归结为全局变量被认为是不好的做法的相同原因。 This answer讨论了其中的一些。
不过,将 request
对象存储在线程本地数据中已成为 Django 社区中广泛使用的模式。甚至还有一个应用程序Django-CRUM它包含一个 CurrentRequestUserMiddleware
类和函数 get_current_user()
和 get_current_request()
。
请注意,从 3.0 版开始,Django 已开始实现 asynchronous support .我不确定它对 Django-CRUM 之类的应用程序有什么影响。然而,在可预见的 future ,线程局部变量可以安全地与 Django 一起使用。
关于python - 在并发请求的情况下,将数据存储在 Django 应用程序中的 "thread local storage"中是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62599950/