一尘不染

Python Django全局变量

django

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

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


阅读 1455

收藏
2020-03-26

共2个答案

一尘不染

你不能声明全局变量。如果设置正确,则设置(常量)可以。但是变量与无共享架构冲突,可能会造成很多麻烦。(最好是它们会不一致)

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

新方法incr()decr()方法特别适用于计数。请参阅文档以获取更多信息。

2020-03-26
一尘不染

你可以将计数器声明为模型类 -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任何操作,则无需采取任何措施。

2020-03-26