Python Django全局变量

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

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

任何意见或建议,不胜感激。谢谢,乔

Joe J asked 2020-08-09T03:47:22Z
3个解决方案
63 votes

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

您可以将计数器声明为模型类成员。 然后,要处理竞争状况,您必须添加一个方法,如果来自另一个线程的其他客户端使用计数器,则该方法将等待。 像这样:

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

nkrkv answered 2020-08-09T03:48:07Z
25 votes

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

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

新的3003241507982935050和300324150798293504504方法尤其适用于计数。 请参阅文档以获取更多信息。

muhuk answered 2020-08-09T03:47:37Z
0 votes

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

Juuso Ohtonen answered 2020-08-09T03:48:27Z
translate from https://stackoverflow.com:/questions/2680902/python-django-global-variables