python - 在并发请求的情况下,将数据存储在 Django 应用程序中的 "thread local storage"中是否安全?

标签 python python-3.x django django-rest-framework python-multithreading

我在很多地方都看到,使用线程本地存储在 Django 应用程序中存储任何数据都不是一个好习惯。 但这是我可以存储我的请求对象的唯一方法。我需要存储它,因为我的应用程序结构复杂。而且我不能继续在每个函数调用或类初始化时传递请求对象。

我需要将我的请求对象中的 cookie 和 header 传递给我在应用程序的不同位置进行的一些 api 调用。

我用这个作为引用: https://blndxp.wordpress.com/2016/03/04/django-get-current-user-anywhere-in-your-code-using-a-middleware/

所以我使用的是中间件,如引用文献中所述。 而且,这就是请求的存储方式

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/

相关文章:

python - 没有 args 参数的 os.execv

python-3.x - 用 Pandas 中的if条件逐列求和

python - 如何与 Django 一起设置连续运行的进程?

python - Celeryd 运行多个守护进程

python - uwsgi - 不使用 virtualenv 中的 python2.7.3,而是使用 venv 中的 2.6,即使 2.6 仅在全局安装

python - 在 Python 中模拟 ImportError

python - 打印每个单词的第一个和最后一个字母的代码

python - 为什么 btclib.mnemonic_from_raw_entropy 声称我传递给它的熵少于 128 位?

python - 在超时中包装 asyncio.gather

python - Django Python __init__() TypeError 'Default' 教程