Django的异步支持

Django 的异步支持机制是通过装饰器兼容实现的,这是 Django 3.1 起引入异步视图支持时的关键设计之一。



✅ 结论:Django 使用 @sync_to_async / @async_to_sync 等机制,通过装饰器在同步异步之间做“桥接”,以实现兼容。



🔧 背后的装饰器机制(核心模块)

Django 使用的是 asgiref 包中的这两个装饰器:

🔁 @sync_to_async

  • 把同步函数变成可等待的异步函数。
  • 应用于 DB 操作、第三方库等必须用 sync 的代码。

🔁 @async_to_sync

  • 把异步函数变成可在同步环境下调用。
  • 用于在传统 WSGI 中调用 async 函数,或中间件适配。


🎯 应用场景举例

1. ✅ 在异步视图中使用同步 ORM(必须加装饰器):

from asgiref.sync import sync_to_async

@sync_to_async
def get_user():
    return User.objects.get(id=1)

async def my_view(request):
    user = await get_user()
    return JsonResponse({'username': user.username})


2. ✅ 在同步中间件或测试环境中运行异步视图

from asgiref.sync import async_to_sync

user = async_to_sync(get_user_async)()


🧠 那 Django 是怎么自动兼容的?

在 Django 的视图分发过程中:

✅ 如果你写了 async def view()

Django 会自动检测这是异步视图,并在 asgiref 的帮助下让它在 ASGI 模式下原生运行。

如果你是在同步(WSGI)环境,比如开发服务器,Django 就会自动用 async_to_sync() 包起来。



⚠️ 补充:Django ORM 本身是同步的!

所以在 async def 视图里,你必须这样包:

await sync_to_async(Model.objects.get)(id=1)

或封装成函数:

@sync_to_async
def get_data():
    return Model.objects.filter(...).values()


✅ 总结一句话:

Django 的异步支持是通过 asgiref.sync 提供的装饰器 sync_to_async 和 async_to_sync 在框架层进行兼容,从而让你可以在同一个项目中混用 sync/async 的代码而不崩溃。


文章标签:

评论(0)