【问题标题】:Python Django Global VariablesPython Django 全局变量
【发布时间】:2010-04-21 07:02:32
【问题描述】:

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

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

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

【问题讨论】:

标签: python django memory variables global


【解决方案1】:

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

您可以将您的计数器声明为模型-成员。然后要处理竞争条件,您必须添加一个方法,如果其他客户端从另一个线程与计数器一起工作,该方法将等待。像这样的:

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

【讨论】:

  • 这正是我想要的。我需要生成一个序列号,每个请求都会增加一个序列号以进行测试。在实际系统中,id 来自外部 API。
  • 这对于玩具项目来说可能是一种可行的方法。但是一旦你开始使用这个类,你就可以保证你的应用程序是不可扩展的。我们有缓存子系统是有原因的。
  • 我使用这种方法将客户端实例化到机器服务,每次实例化它都会降低我的网络服务器的速度......
  • 每个应用程序都需要可扩展吗?
  • 考虑到 GIL,线程部分是否必要?是否存在 django 配置,其中实际的多线程在进程中发生并且竞争条件是一个问题?
【解决方案2】:

不得声明全局变量。如果操作正确,设置(常数)就可以了。但是变量违反了 shared-nothing 架构,可能会带来很多麻烦。 (最好的情况是它们会不一致)

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

新的incr()decr() 方法特别适合计数。请参阅 docs 了解更多信息。

【讨论】:

  • 我喜欢这种方法,并且正在实施它。目前,我在 Django 开发服务器上使用 localmem 作为缓存后端,并注意到在浏览我网站中的多个网页后计数不会持续存在。 (当时我没有重新启动 django 开发服务器)我意识到这可能有多种原因。 (最终我将使用 memcached)。只是想知道 localmem 缓存/django 开发服务器是否没有长时间保存缓存值,或者我的配置设置是否有误。
  • @Joe:在没有适当的缓存后端(例如 memcached)的情况下,我总是使用数据库缓存。只是要确定。这与“在性能问题明显之前完全不担心”和“在优化之前测量”是相辅相成的。
  • @muhuk 我有一个关于 Django 视图中的全局变量的问题。可以请提供您的意见吗? stackoverflow.com/questions/39490843/django-app-level-variables
  • @PankajSinghal 我已经阅读了你的问题。中间件似乎是一个不错的选择。但我可能不是最适合回答的人,我与 Django 合作已经很长时间了。
  • 我做到了。我已经有一段时间没有专业地编写 Python 代码了。最好从最新的人那里获得反馈。
【解决方案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文件,而且很容易管理。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2012-09-30
      • 2019-07-24
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多