在Django中创建单例,或其他方式按请求提供全局对象

3 投票
1 回答
4539 浏览
提问于 2025-04-17 08:30

在开发“部件”(就是一些对象,渲染后会用到一些自定义的JavaScript文件)时,我遇到了一个问题:需要创建一个“脚本管理器”,这样可以避免在同一个视图中渲染多个部件时重复加载同一个JavaScript文件。

我最初的想法是写一个自定义的模板渲染上下文,这样可以在模板中提供一个叫做 EXTRA_SCRIPTS 的变量。不过我不知道在处理请求的过程中,应该在哪里收集这些脚本的列表?我觉得这时候可能需要一个 单例 对象。

有没有什么建议呢?

1 个回答

3

如果你使用单例模式,就可能会遇到线程安全的问题。举个例子,如果你的应用程序同时在多个线程中运行,一个线程处理一个请求,那么你全局的对象应该是每个线程各自独立的,但单例模式在一个进程中是唯一的。

你可以使用 threading.local 技术,就像在这个问题中描述的那样。这样可以为每个线程提供一个独特的对象,也就是每个请求都有自己的对象。

不过,这种做法并不推荐,所以不要使用全局变量

关于你提到的小部件(widgets),在Django中有媒体设置(Media settings)可以用在小部件和表单中。你可以查看这个链接了解更多信息:https://docs.djangoproject.com/en/1.3/topics/forms/media/

媒体对象也可以进行合并。当两个媒体对象合并时,结果的媒体对象会包含两个文件的媒体内容。

所以你可以通过媒体来避免重复的内容。你也可以直接在模板中组合媒体。

{{ form.media|add:info_form.media|add:discount_form.media }}

撰写回答