我在Django中寻找简单但推荐的方法,只在内存中存储变量。当Apache重新启动或Django开发服务器重新启动时,该变量将重置为0.更具体地说,我想计算每个模型实例(数据库记录)上发生特定操作的次数,但出于性能原因,我不知道我想将这些计数存储在数据库中。我不在乎服务器重启后计数是否消失。但只要服务器启动,我希望这些计数在Django shell和Web界面之间保持一致,并且我希望能够返回每个模型实例上执行操作的次数。
我不希望变量与用户或会话相关联,因为我可能希望在不登录的情况下返回这些计数(并且我希望无论用户登录什么计数都是一致的)。我在描述一个全局变量吗?如果是这样,我如何在Django中使用一个?我注意到像urls.py,settings.py和models.py这样的文件似乎每个服务器启动时只被解析一次(与views.py相比,这似乎是在发出请求的时候解析的)。这是否意味着我应该在其中一个文件中声明我的变量?或者我应该以某种方式将它存储在模型属性中(只要它在服务器运行时就会存在)?这可能是一个简单的问题,但我不确定它是如何在Django中完成的。
非常感谢任何评论或建议。 谢谢, 乔
答案 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也会保证一致性。