Python Django全局变量

eqqqjvef  于 2023-06-20  发布在  Python
关注(0)|答案(6)|浏览(170)

我正在寻找简单但推荐的方式在Django中存储一个变量只在内存中。当Apache重新启动或Django开发服务器重新启动时,变量将重置为0。更具体地说,我想计算一个特定的动作在每个模型示例(数据库记录)上发生了多少次,但出于性能原因,我不想在数据库中存储这些计数。我不在乎服务器重启后计数是否消失。但是只要服务器处于运行状态,我希望这些计数在Django shell和web界面之间保持一致,并且我希望能够返回在每个模型示例上发生了多少次操作。
我不希望变量与用户或会话相关联,因为我可能希望在没有登录的情况下返回这些计数(并且我希望无论哪个用户登录,计数都是一致的)。我在描述一个全局变量吗?如果是,我如何在Django中使用一个?我注意到像www.example.com、www.example.com和www.example.com这样的文件似乎在每次服务器启动时只解析一次(与之形成对比的是,www.example.com似乎在每次发出请求时都要解析一次)。urls.py或者我应该以某种方式将其存储在模型属性中(只要它在服务器运行时一直存在)?settings.py and models.py seems to be parsed only once per server startup (by contrast to the views.py which seems to be parsed eache time a request is made). Does this mean I should declare my variables in one of those files? Or should I store it in a model attribute somehow (as long as it sticks around for as long as the server is running)? This is probably an easy question, but I'm just not sure how it's done in Django.
任何意见或建议都非常感谢。谢谢,乔

c86crjj0

c86crjj01#

为什么不能声明全局变量?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进行实验,则不需要执行任何操作。

vlurs2pr

vlurs2pr2#

不能声明全局变量。设置(常量)如果正确,则可以。但是变量违反了 shared-nothing 架构,可能会引起很多麻烦。(最好的情况是它们不一致)
我会简单地将这些统计数据存储在该高速缓存中。(好吧,实际上我会将它们存储在数据库中,但你明确表示你 * 相信 * 它会对性能产生负面影响,所以......)
新的incr()decr()方法特别适用于计数。更多信息请参阅文档。

pftdvrlh

pftdvrlh3#

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

55ooxyrt

55ooxyrt4#

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

vq8itlhq

vq8itlhq5#

您可以使用www.example.com中的变量settings.py
参见下面的示例。这是一个计算请求的应用程序

settings.py

REQ_COUNTER = 0

View.py

from {**your project folder name **}.settings import REQ_COUNTER 

def CountReq(request):
 global = REQ_COUNTER
 REQ_COUNTER = REQ_COUNTER + 1
 return HttpResponse(REQ_COUNTER)

Thanks:)

x9ybnkn6

x9ybnkn66#

Manager可以用来在主进程启动的所有Django子进程之间共享变量:

from multiprocessing import Manager
from rest_framework.decorators import api_view
from rest_framework.response import Response

total_count = Manager().Value('i', 0)

@api_view(['GET'])
def hello_count(request):
    total_count.value = total_count.value + 1
    return Response(data={'count': total_count.value})

对于所有正在运行的进程,total_count将增加(使用gunicorn应用服务器运行的多个工作进程进行检查)。
但是,如果您运行python manage.py shell,则该进程的total_count将是0,因为这是一个具有自己内存空间的独立主进程。如果你想为服务器(甚至多个服务器)内的所有进程获取相同的共享值,你必须使用内存中的DB(redis等),对于生产环境来说,什么是更好、更稳定的做法呢?

相关问题