Python Django обновление переменной в шаблоне во время работы функции в фоновом режиме
У меня есть простой шаблон, в котором есть кнопка:
<a class="button" href="{% url 'function' %}">
<button>
Settings
</button>
</a>
И views.py
в котором у меня есть определение функции.
def function(request):
context = {}
object = Runner()
object.prepate_sth()
context['tasks'] = runner.tasks.remaining
try:
thread = threading.Thread(target=runner.run_sth, args=())
thread.start()
except Exception:
raise Exception
return render(request, 'home.html', context)
Я создаю отдельный поток для того, чтобы не блокировать выполнение функции и запустить в фоновом режиме какую-то другую функцию. Эта задача в фоновом режиме изменяет количество элементов в переменной списка runner.tasks.remaining
. Я бы хотел, чтобы эта переменная отображалась в шаблоне и постоянно обновлялась при изменении ее значения. Как я могу этого добиться?
Вы можете использовать Django Session & Cookies для постоянного обновления значений переменных.
Вот документация по использованию сессий и cookies
В Django короткий ответ - нельзя. Как только HTML/шаблон отображается на стороне клиента, вы не можете изменить его без обновления, а при текущем способе, который вы используете, поток будет перезапускаться, поэтому он всегда будет показывать это начальное значение.
С помощью Javascript & Websockets, или просто кучи постов Javascript Ajax every x seconds
, вы можете постоянно пинговать сервер и получать ответ с прогрессом потока и обновлять HTML... но даже это вызывает проблемы:
- Вам нужно иметь доступ к переменной, которую изменяет поток.
- Вам нужно отслеживать, какой поток для какого пользователя.
Решение, вероятно, состоит в том, чтобы поток обновлял значение внутри кэша, с ключом типа {user}_tasks
. Поток будет обновлять кэш. Представление, которое вы пингуете, просто возвращает кэшированное значение в JS, который затем обновляет значение в HTML.
.
Возможно, вы также захотите отслеживать, запущен ли уже поток для данного пользователя, чтобы при обновлении страницы не запустить еще один - или он убьет первоначальный и начнет все сначала.
Или вместо того, чтобы использовать кэш, ну, сессии - это в основном кэш, вы можете использовать движок сессий вместо работы напрямую с кэшем, как указал @Abu Nayem.
В любом случае, это довольно сложный процесс с большим количеством движущихся частей. Я указал основные проблемы, с которыми вы столкнетесь, но, скорее всего, есть еще много других