Python Django全局变量

57 投票
6 回答
71650 浏览
提问于 2025-04-15 21:52

我想在Django中找到一种简单但推荐的方法来只在内存中存储一个变量。当Apache重启或Django开发服务器重启时,这个变量会重置为0。更具体地说,我想统计每个模型实例(数据库记录)上某个特定操作发生的次数,但出于性能考虑,我不想把这些计数存储在数据库里。我不在乎这些计数在服务器重启后消失。只要服务器在运行,我希望这些计数在Django命令行和网页界面之间保持一致,并且我希望能够返回每个模型实例上这个操作发生了多少次。

我不想让这些变量和用户或会话关联,因为我可能想在未登录的情况下返回这些计数(而且我希望这些计数在任何用户登录时都保持一致)。我是在描述一个全局变量吗?如果是的话,我该如何在Django中使用它?我注意到像urls.py、settings.py和models.py这样的文件似乎在服务器启动时只解析一次(而views.py似乎每次请求时都会解析)。这是否意味着我应该在这些文件中的一个地方声明我的变量?还是应该以某种方式将它存储在模型属性中(只要它在服务器运行期间保持有效)?这可能是个简单的问题,但我不太确定在Django中该怎么做。

任何评论或建议都非常感谢。

谢谢,

6 个回答

3

我会在根目录下创建一个叫“config.py”的文件,然后把所有的全局变量放在里面:

x = 10
my_string = ''

在“view.py”文件中:

from your_project import config

def MyClass(reuqest):
    y = config.x + 20
    my_title = config.my_string
...

这样做的好处是,这些变量可以在多个.py文件之间共享,而且管理起来也很方便。

76

为什么不应该声明全局变量呢?这听起来有点像宣传。如果作者知道自己想要什么,并且清楚会有什么副作用,那为什么不呢?也许这只是一个快速的实验。

你可以把计数器声明为一个模型的成员。为了处理竞争条件,你需要添加一个方法,这个方法会在其他线程的客户端正在使用计数器时等待。大概是这样的:

import threading

class MyModel(ModelBase):
    _counter = 0
    _counter_lock = threading.Lock()

    @classmethod
    def increment_counter(cls):
        with cls._counter_lock:
            cls._counter += 1

    def some_action(self):
        # core code
        self.increment_counter()


# somewhere else
print MyModel._counter

不过要记住:你的应用程序必须在一个进程中运行。所以如果你是在Apache下部署应用,确保它配置为生成多个线程,而不是多个进程。如果你是在实验./manage.py run,那就不需要做任何额外的操作。

24

不应该声明全局变量。如果是设置(常量),那可以,但要正确使用。变量会和无共享架构相冲突,可能会引发很多麻烦。(最好的情况是它们会变得不一致)

我建议把这些统计数据存储在缓存中。(其实我会把它们存到数据库里,但你已经明确表示你认为这样会对性能产生负面影响,所以……)

新的incr()decr()方法特别适合用来计数。想了解更多信息,可以查看文档

撰写回答