渲染视图后如何做某事? (Django的)

时间:2009-07-04 02:16:36

标签: python django

我想在使用

渲染视图后做一些事情
return render_to_response()

信号是唯一的方法吗?我是否需要编写自定义信号或request_finished给我足够的信息?基本上我需要知道呈现了什么页面,然后做出响应的动作。

感谢。

评论更新:我不想阻止页面的渲染,所以我想首先渲染页面,然后再进行操作。

7 个答案:

答案 0 :(得分:11)

您生成一个单独的线程并让它执行操作。

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响应并终止初始线程之后,该线程仍将继续工作。例如,它可以发送电子邮件而不会延迟响应。

答案 1 :(得分:5)

如果你有一个长期运行的过程,你有两个简单的选择。

  1. 在发送响应页面之前产生子进程。

  2. 创建“后台服务守护程序”并将工作请求传递给它。

  3. 这都在Django之外。您可以使用subprocess或其他一些IPC方法与其他进程通信。

答案 2 :(得分:4)

执行此操作的常用方法是使用消息队列。您在队列上放置一条消息,工作线程(或进程等)使用队列并在视图完成后执行工作。

Google App Engine具有任务队列api http://code.google.com/appengine/docs/python/taskqueue/,亚马逊拥有简单队列服务http://aws.amazon.com/sqs/

快速搜索没有发现看起来像公认标准的任何django可插件。

模拟功能的快速而肮脏的方法是将“消息”放在数据库表中,并让cron作业定期检查表以执行工作。

答案 3 :(得分: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())

迭代器的正常使用是发送大数据而不将其全部读入内存。例如,从文件中读取块并适当地生成。我从来没有以这种方式使用它,但它似乎应该有效。

答案 4 :(得分:2)

我最喜欢的解决方案:处理后台任务的单独进程,通常是索引和发送通知邮件等。然后,在视图呈现期间,您将事件发送到事件处理系统(我不知道是否Django有一个内置,但你总是需要一个,所以你应该有一个)然后偶数系统将消息放入一个消息队列(除非你有多个机器或多个后台进程,这是很容易写,除非你有多个机器或多个后台进程)执行任务问题

答案 5 :(得分:-1)

在渲染到响应时,您传递要显示的html页面。其他页面需要发送一个帖子(通过Javascript或其他东西)来触发视图中的正确功能,然后该视图会调用正确的下一页显示。

答案 6 :(得分:-1)

也许我不明白你的问题。但为什么不是简单的事情:

try:
    return render_to_response()
finally:
    do_what_needs_to_be_done()