【问题标题】:How to call asynchronous function in Django?如何在 Django 中调用异步函数?
【发布时间】:2020-06-15 14:25:30
【问题描述】:

以下不执行 foo 并给出 RuntimeWarning: coroutine 'foo' was never awaited

# urls.py

async def foo(data):
    # process data ...

@api_view(['POST'])
def endpoint(request):
    data = request.data.get('data')
    
    # How to call foo here?
    foo(data)

    return Response({})

【问题讨论】:

  • await foo(data) ?
  • await foo(data)SyntaxError: invalid syntax
  • 你的视图函数必须用async关键字定义

标签: python django django-rest-framework python-3.6 django-3.0


【解决方案1】:

Django 是一种同步语言,但它支持异步行为。 分享代码 sn-p 可能会有所帮助。

    import asyncio
    from channels.db import database_sync_to_async

    def get_details(tag):
        response = another_sync_function()

        # Creating another thread to execute function
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        async_result = loop.run_until_complete(remove_tags(response, tag))
        loop.close()

    # Async function 
    async def remove_tags(response, tag_id):
        // do something here

        # calling another function only for executing database queries
        await tag_query(response, tag_id)

   @database_sync_to_async
   def tag_query(response, tag_id):
        Mymodel.objects.get(all_tag_id=tag_id).delete()

这样我在同步函数中调用了异步函数。

Reference for database sync to async decorator

【讨论】:

    【解决方案2】:

    找到了一种方法。

    在与urls.py 相同的目录中创建另一个文件bar.py

    # bar.py
    
    def foo(data):
        // process data
    
    # urls.py
    
    from multiprocessing import Process
    from .bar import foo
    
    @api_view(['POST'])
    def endpoint(request):
        data = request.data.get('data')
    
        p = Process(target=foo, args=(data,))
        p.start()
    
        return Response({})
    

    【讨论】:

    • 尝试使用 data 作为表单,foo 作为处理该表单的函数(或更正确;根据表单中的值更改某些值)。那没用...
    【解决方案3】:

    不能在这种情况下等待 foo。看到Django主要是一个同步库,它与异步代码的交互并不好。我能给它的最好建议是尽量避免在这里使用异步函数,或者使用另一种并发方法(即线程或多处理)。

    注意:关于 Django 的同步特性给出了一个很好的答案,可以在这里找到:Django is synchronous or asynchronous?

    【讨论】:

    • Django 3.X 支持异步
    • 你如何有其他没有异步的并发方法?您希望获得什么好处?
    猜你喜欢
    • 2020-03-09
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多