Подтвердить что ты не робот

Глобальные переменные Python Django

Я ищу простой, но рекомендуемый способ в Django для хранения переменной только в памяти. Когда перезапускается Apache или сервер разработки Django, переменная reset возвращается к 0. Более конкретно, я хочу подсчитать, сколько раз определенное действие происходит на каждом экземпляре модели (запись базы данных), но по соображениям производительности я не хотите хранить эти подсчеты в базе данных. Меня не волнует, исчезли ли счеты после перезапуска сервера. Но пока сервер работает, я хочу, чтобы эти подсчеты были согласованы между оболочкой Django и веб-интерфейсом, и я хочу иметь возможность вернуть, сколько раз действие было выполнено на каждом экземпляре модели.

Я не хочу, чтобы переменные были связаны с пользователем или сеансом, потому что я мог бы захотеть вернуть эти счеты без входа в систему (и я хочу, чтобы подсчеты были согласованы независимо от того, какой пользователь входит в систему). Я описываю глобальную переменную? Если да, то как я могу использовать его в Django? Я заметил, что файлы, такие как urls.py, settings.py и models.py, по-видимому, анализируются только один раз для запуска сервера (в отличие от view.py, который, как представляется, обрабатывается временем eache, когда запрос выполняется). Означает ли это, что я должен объявить свои переменные в одном из этих файлов? Или мне следует каким-то образом сохранить его в атрибуте модели (если он работает до тех пор, пока сервер работает)? Это, наверное, простой вопрос, но я просто не уверен, как это делается в Django.

Любые комментарии или советы очень ценятся. Благодаря, Джо

4b9b3361

Ответ 1

Вы не должны объявлять глобальные переменные. Настройки (константы) в порядке, если все сделано правильно. Но переменные нарушают архитектуру без общего доступа и могут вызвать множество проблем. (в лучшем случае они будут непоследовательными)

Я бы просто сохранил эту статистику в кеше. (Хорошо, я бы сохранил их в базе данных, но вы поняли, что считаете, что это окажет негативное влияние на производительность, поэтому...)

Новые методы incr() и decr() особенно подходят для подсчета. Подробнее см. docs.

Ответ 2

Почему один не должен объявлять глобальные переменные? 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, никаких действий не требуется.

Ответ 3

Если вы хотите избежать хлопот с базой данных Django, например, проблемы миграции или производительности, вы можете рассмотреть базу данных в памяти redis. Redis гарантирует согласованность, даже если есть несколько процессов Django.