web-dev-qa-db-ja.com

Python Djangoグローバル変数

Django=変数をメモリのみに保存するためのシンプルだが推奨される方法を探しています。Apacheが再起動するとき、またはDjango開発サーバーが再起動するとき、変数は具体的には、各モデルインスタンス(データベースレコード)で特定のアクションが実行される回数をカウントしますが、パフォーマンス上の理由から、これらのカウントをデータベースに保存したくありません。サーバーの再起動後にカウントが消えてもかまいませんが、サーバーが稼働している限り、これらのカウントがDjango ShellとWebインターフェース間で一貫していることを望みます。各モデルインスタンスでアクションが実行された回数を返すことができます。

ログインせずにこれらのカウントを返したい場合があるため、変数をユーザーまたはセッションに関連付けたくありません(そして、どのユーザーがログインしていてもカウントを一貫させたい)。グローバル変数を記述していますか?その場合、Djangoでどのように使用しますか? urls.py、settings.py、models.pyなどのファイルは、サーバーの起動ごとに1回だけ解析されるようです(views.pyはリクエストが行われるたびに解析されるようです)。これは、これらのファイルの1つで変数を宣言する必要があるということですか?または、何らかの方法でモデル属性に保存する必要があります(サーバーが実行されている限り、それが保持されている限り)。これはおそらく簡単な質問ですが、Djangoでどのように実行されるかはわかりません。

コメントやアドバイスは大歓迎です。ありがとう、ジョー

42
Joe J

あなたはグローバル変数を宣言する必要はありません。設定(定数)は、正しく行われればOKです。しかし、変数はshared-nothingアーキテクチャに違反しており、多くの問題を引き起こす可能性があります。 (最良の場合、彼らは矛盾するでしょう)

これらの統計をキャッシュに保存するだけです。 (まあ、実際にそれらをデータベースに保存しますが、believeそれがパフォーマンスに悪影響を与えることを明確にしたので...)

新しいincr()およびdecr()メソッドは、カウントに特に適しています。詳細については、 docs を参照してください。

25
muhuk

する必要はありませんがグローバル変数を宣言するのはなぜですか? O_o。それはただの宣伝のように見えます。作者が自分が何を望んでいて、どんな副作用が起こるかを知っているなら、なぜだろう。たぶん簡単な実験だろう。

カウンターをモデルclass-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

ただし、アプリケーションを1つのprocessに含める必要があります。そのため、アプリケーションをApacheでデプロイした場合、多くのプロセスを生成するのではなく、多くのスレッドを生成するように構成してください。 ./manage.py runを試す場合、アクションは不要です。

63
nkrkv

Djangoデータベース、移行やパフォーマンスの問題など)で面倒を避けたい場合は、インメモリデータベース redis を検討することができます。 Djangoプロセス。

0
Juuso Ohtonen