Как вы делаете что-то после визуализации представления? (Джанго)

Я хочу сделать что-то после того, как я отобразил представление, используя

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 или что-то еще), которое запускает правильную функцию в ваших представлениях, тогда это представление вызывает правильную следующую страницу для отображения.