Python 在主循环中处理请求时,如何从django视图运行异步函数以在后台运行?

Python 在主循环中处理请求时,如何从django视图运行异步函数以在后台运行?,python,django,multithreading,asynchronous,Python,Django,Multithreading,Asynchronous,正如我在标题中所说,我希望在后台运行一个任务,处理一个大型数据库查询,同时处理来自前端的请求。我甚至可以用async/asyncio来实现吗?有人告诉我这是可能的 出于上下文的目的,我想做如下事情。另外请注意,我并不需要函数来告诉我什么时候完成了,尽管我确实想知道这是否可行,因为我只是检查.json文件是否最终被写入 def post_data_view(request): if request.method == 'POST': ... do_long

正如我在标题中所说,我希望在后台运行一个任务,处理一个大型数据库查询,同时处理来自前端的请求。我甚至可以用async/asyncio来实现吗?有人告诉我这是可能的

出于上下文的目的,我想做如下事情。另外请注意,我并不需要函数来告诉我什么时候完成了,尽管我确实想知道这是否可行,因为我只是检查.json文件是否最终被写入


def post_data_view(request):
    if request.method == 'POST':
        ...
        do_long_query_in_the_background(some_data)
        return HttpResponse('Received. Ask me in a while if I finished.')

def is_it_done_view(request):
    if request.method == 'GET':
        data = find_json()
        if data:
            return JsonResponse(data)
        else:
            return HttpResponse('Not yet dude...')

async def do_long_query_in_the_background(data):
    # do some long processing...
    # dump the result to a result.json
    return
有人告诉我,使用async可以做到这一点,但我真的很难理解。就上下文而言,我试图将其简化很多,但即便如此,我还是发现自己不太明白发生了什么:


async def f():
    while True:
        print(0)
        await asyncio.sleep(2)

asyncio.create_task(f())
即使我尝试的这段代码也失败了sys:1:RuntimeWarning:coroutine'f'从未被等待过,但它在控制台上确实可以工作,我不明白为什么会这样

我还想知道这是否是所有可能的和安全的线程可能吗

我对此感到非常沮丧,因为在其他线程中建议的一般解决方案似乎只是使用芹菜,但对于一个不太复杂的问题来说,这真的感觉像是一种过激的行为。

async def f: 尽管如此: 打印0 等待asyncio.sleep2 asyncio.runf asyncio中的run方法设置事件循环并创建任务对象,安排它运行并等待它完成,然后再执行任何其他代码

虽然异步编程看起来很简单,但它需要一种非常不同的编程方法,因为事情可能以任何顺序发生,并且您必须非常仔细地考虑什么顺序对函数的完成非常重要

不过,对于您的用例,您可能可以使用线程。您可以创建一个新线程,只要它在后台运行。在线程之间切换会导致性能下降,但如果大部分处理都在服务器端完成,用户可能会有更好的体验

这将永远运行,因为循环永远不会终止 从线程导入线程 从时间上导入睡眠 def f: 尽管如此: 打印0 等待asyncio.sleep2 def主: 打印“开始新线程…” t=Threadtarget=f t、 开始 打印“继续其他任务…” 睡觉 打印“还有更多事情要做…” 您需要使用aync定义视图函数。在您的情况下,它应该是:async def post_data_viewrequest: 在异步视图函数中:首先需要获取循环。然后在循环中创建一个任务。应该是:
如果您在end@el_osoSyntaxError:函数外部的“wait”听起来好像没有运行事件循环。您是否创建了事件循环?
    async def post_data_view(request):
        if request.method == 'POST':
        ....
        loop = asyncio.get_event_loop()
        loop.create_task(do_long_query_in_the_background(some_data))
        return HttpResponse('Received. Ask me in a while if I finished.')