【问题标题】:Django-Channels AsyncConsumer not workingDjango-Channels AsyncConsumer 不工作
【发布时间】:2020-08-03 08:23:11
【问题描述】:

使用SyncConsumer 和下面的代码可以正常工作

class BackgroundTaskConsumer(SyncConsumer):
    def create_users(self, message):
        number = message['number']
        id = message['id']
        UserFactory.create_batch(number, groups=(id,))

但是当使用AsyncConsumer 和下面的代码时停止工作

class BackgroundTaskConsumer(AsyncConsumer):
    async def create_users(self, message):
        number = message['number']
        id = message['id']
        await UserFactory.create_batch(number, groups=(id,))

【问题讨论】:

    标签: django python-asyncio django-channels


    【解决方案1】:

    您需要在 database_sync_to_async 中扭曲数据库操作。

    class BackgroundTaskConsumer(AsyncConsumer):
        async def create_users(self, message):
            number = message['number']
            id = message['id']
            await database_sync_to_async(UserFactory.create_batch)(number, groups=(id,))
    

    你使用database_sync_to_async的方式确实有点奇怪

    你以你的方式包装你调用的函数的原因是确保它在被调用之前被包装。

    如果你这样做,在 python 中

    a = c(b())
    

    b()c(..) 之前被调用。

    但是database_sync_to_async 需要在您访问数据库之前之后做一些事情。

    通常在 python 中你会使用with contextManager 来执行此操作,但这与从async 转换为sync 不兼容。

    所以通过wrapping 你的UserFactory.create_batch 方法然后返回一个你可以用create_batch 调用的新方法。这与@decorator 的工作原理相同

    【讨论】:

    • 谢谢。在职的。你能解释一下为什么参数number, groups=(id,)database_sync_to_async之外
    猜你喜欢
    • 2022-12-05
    • 2016-10-22
    • 2023-03-28
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多