Как вы делаете что-то после визуализации представления? (Джанго)
Я хочу сделать что-то после того, как я отобразил представление, используя
return render_to_response()
Являются ли сигналы единственным способом сделать это? Нужно ли мне писать пользовательский сигнал или request_finished дать мне достаточно информации? В основном мне нужно знать, какая страница была отображена, а затем выполнить действие в ответ на это.
Спасибо.
ОБНОВЛЕНИЕ ОТ КОММЕНТАРИЙ: Я не хочу задерживать рендеринг страницы, поэтому сначала хочу отобразить страницу, а затем выполнить действие.
Ответы
Ответ 1
Вы создаете отдельный поток и выполняете действие.
t = threading.Thread(target=do_my_action, args=[my_argument])
# We want the program to wait on this thread before shutting down.
t.setDaemon(False)
t.start()
Это приведет к тому, что "do_my_action (my_argument)" будет выполнен во втором потоке, который будет работать даже после отправки ответа Django и завершения начального потока. Например, он может отправить электронное письмо без задержки ответа.
Ответ 2
Если у вас длительный процесс, у вас есть два простых варианта.
Это все за пределами Django. Вы используете subprocess или какой-либо другой метод IPC для связи с другим процессом.
Ответ 3
Общим способом сделать это является использование очередей сообщений. Вы размещаете сообщение в очереди, а рабочие потоки (или процессы и т.д.) Потребляют очередь и выполняют работу после завершения просмотра.
Google App Engine имеет очередь задач api http://code.google.com/appengine/docs/python/taskqueue/, у amazon есть служба простой очереди http://aws.amazon.com/sqs/.
В результате быстрого поиска не появилось никаких подключаемых устройств django, которые выглядят как принятые стандарты.
Быстрый и грязный способ эмуляции функций состоит в том, чтобы поместить "сообщение" в таблицу базы данных и периодически выполнять задание cron для проверки работы.
Ответ 4
Объект Django HttpResponse принимает итератор в своем конструкторе:
http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators
Итак, вы можете сделать что-то вроде:
def myiter():
yield "my content"
enqueue_some_task()
return
def myview(request):
return HttpResponse(myiter())
Обычное использование итератора - отправка больших данных без чтения всего этого в память. Например, прочитайте фрагменты из файла и выполните соответствующие действия. Я никогда не использовал его таким образом, но, похоже, он должен работать.
Ответ 5
Мое любимое решение: отдельный процесс, который обрабатывает фоновые задачи, обычно такие вещи, как индексирование и отправка уведомлений и т.д. И затем во время рендеринга представления вы отправляете событие в систему обработки событий (я не знаю, будет ли Django имеет один встроенный, но вы всегда нуждаетесь в нем в любом случае, поэтому у вас должен быть такой), а четная система помещает сообщение в очередь сообщений (что тривиально писать, если у вас нет нескольких машин или нескольких фоновых процессов), которые выполняют задачу в вопрос.
Ответ 6
Возможно, я не понимаю ваш вопрос. Но почему бы не просто так:
try:
return render_to_response()
finally:
do_what_needs_to_be_done()
Ответ 7
В режиме рендеринга вы передаете страницу html, которую вы хотите отобразить. На другой странице необходимо отправить сообщение (через Javascript или что-то еще), которое запускает правильную функцию в ваших представлениях, тогда это представление вызывает правильную следующую страницу для отображения.