Python Django全局变量

时间:2010-04-21 07:02:33

标签: python django memory variables global

我在Django中寻找简单但推荐的方法,只在内存中存储变量。当Apache重新启动或Django开发服务器重新启动时,该变量将重置为0.更具体地说,我想计算每个模型实例(数据库记录)上发生特定操作的次数,但出于性能原因,我不知道我想将这些计数存储在数据库中。我不在乎服务器重启后计数是否消失。但只要服务器启动,我希望这些计数在Django shell和Web界面之间保持一致,并且我希望能够返回每个模型实例上执行操作的次数。

我不希望变量与用户或会话相关联,因为我可能希望在不登录的情况下返回这些计数(并且我希望无论用户登录什么计数都是一致的)。我在描述一个全局变量吗?如果是这样,我如何在Django中使用一个?我注意到像urls.py,settings.py和models.py这样的文件似乎每个服务器启动时只被解析一次(与views.py相比,这似乎是在发出请求的时候解析的)。这是否意味着我应该在其中一个文件中声明我的变量?或者我应该以某种方式将它存储在模型属性中(只要它在服务器运行时就会存在)?这可能是一个简单的问题,但我不确定它是如何在Django中完成的。

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

4 个答案:

答案 0 :(得分:60)

为什么一个必须声明全局变量? O_O。它看起来像一个宣传。如果作者知道他想要什么以及会有什么副作用,为什么不呢。也许这只是一个快速的实验。

您可以将计数器声明为模型 -member。然后,为了处理竞争条件,你必须添加一个方法,如果某个其他客户端,从另一个线程使用计数器,它将等待。像这样:

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,则无需执行任何操作。

答案 1 :(得分:25)

不得声明全局变量。如果正确完成,设置(常量)都可以。但变量违反无共享架构,可能会造成很多麻烦。 (最好的情况是它们会不一致)

我只是将这些统计信息存储在缓存中。 (好吧,实际上我会将它们存储在数据库中,但你明确表示你相信它会对性能产生负面影响,所以...)

新的incr()decr()方法特别适合计算。有关详细信息,请参阅 docs

答案 2 :(得分:1)

我会在根目录上创建一个“ 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文件,并且易于管理。

答案 3 :(得分:0)

如果您想避免使用Django数据库的麻烦,例如迁移或性能问题,则可以考虑使用内存数据库redis。即使有多个Django进程,Redis也会保证一致性。