Python Django Глобальные переменные - PullRequest
41 голосов
/ 21 апреля 2010

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

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

Любые комментарии или советы высоко ценится. Спасибо, Джо

Ответы [ 2 ]

61 голосов
/ 21 апреля 2010

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

25 голосов
/ 21 апреля 2010

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

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

Новые методы incr() и decr() особенно подходят для подсчета. См. документы для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...