有没有办法从Python [Django] 中进行异步函数调用?

8 投票
4 回答
9016 浏览
提问于 2025-04-15 13:57

我正在创建一个Django应用程序,这个程序需要对上传的文件进行一些比较长的计算。我不想让用户在处理文件时一直等待——我只想给用户显示一个页面,上面写着“文件正在解析中”。

我该如何在视图中调用一个异步函数呢?

这可能看起来像这样:

def view(request):
    ...
    if form.is_valid():
        form.save()
        async_call(handle_file)
    return render_to_response(...)

4 个回答

0

除非你特别需要使用一个单独的进程,这似乎是S.Lott提到的其他问题的核心内容,否则Python标准库中的threading模块可能是最简单的解决方案。你只需要确保handle_file这个函数不要访问任何可能被修改的全局变量,尤其是不要自己去修改全局变量;理想情况下,它应该通过Queue实例与程序的其他部分进行沟通;等等,关于线程的所有常规建议都适用;-)。

2

我也试过做同样的事情,但因为Django的特性和其他异步调用,尝试了好几次都失败了。

我想到的解决办法可能对你来说有点复杂,就是在后台再加一个异步服务器,专门处理来自网页请求的消息队列,然后发送一些分块的JavaScript代码,这些代码可以直接在浏览器中异步解析(也就是用ajax)。

通过mod_proxy的设置,所有这些对最终用户来说都是透明的,也就是说用户不会感觉到这些复杂的操作。

8

与其通过子进程或线程来管理这个问题,我建议你完全把它分开。这里有两种方法:第一种是在某个数据库表里设置一个标志,然后定期运行一个定时任务,检查这个标志并执行所需的操作。

第二种选择是使用消息队列。你的文件上传过程会在队列上发送一条消息,然后一个单独的监听器会接收这条消息并进行相应的处理。我用过RabbitMQ来做这种事情,但还有其他的选择。

无论哪种方式,用户都不需要等待这个过程完成,你也不需要担心管理子进程的问题。

撰写回答