Django 5异步信号asend报错:unhashable type: list 求助
问题分析
报错TypeError: unhashable type: 'list'出现在asyncio.gather调用中,说明传递给该方法的参数包含了列表(而非合法的可等待对象)。结合Django 5信号源码逻辑,核心原因大概率是Signal.asend()方法未正确将同步信号发送逻辑包装为异步可等待对象,导致直接把同步调用返回的列表传入了asyncio.gather。
解决方案
方案1:升级/重新安装官方稳定版Django
确保使用Django 5.0正式发布版本(而非测试版/开发版),重新安装修复可能存在的源码bug:
pip install --upgrade django==5.0
方案2:手动拆分信号发送逻辑(临时兼容方案)
如果暂时无法升级Django,可以绕过asend()方法,手动拆分同步/异步接收器的调用逻辑:
from asgiref.sync import sync_to_async from django.dispatch import Signal, receiver from django.http import JsonResponse from django.contrib.auth.models import User import asyncio # 信号定义 user_registered_async = Signal() # 异步接收器(添加dispatch_uid避免重复注册) @receiver(user_registered_async, dispatch_uid="unique_async_welcome_email") async def async_send_welcome_email(sender, **kwargs): print("Sending welcome email...") await asyncio.sleep(5) print("Email sent") # 视图代码 async def confirm_email_async(request, code): # 处理同步接收器(如果存在) await sync_to_async(user_registered_async.send)(sender=User) # 直接调用异步接收器处理逻辑 await user_registered_async._send_async(sender=User, named={}) return JsonResponse({"status": "ok"})
方案3:排查接收器重复注册问题
检查代码中是否存在重复注册同一接收器的情况,通过dispatch_uid参数确保接收器唯一注册,避免信号内部处理逻辑出现异常:
@receiver(user_registered_async, dispatch_uid="unique_async_email_sender") async def async_send_welcome_email(sender, **kwargs): print("Sending welcome email...") await asyncio.sleep(5) print("Email sent")
内容的提问来源于stack exchange,提问作者KaronatoR
相关产品推荐
相关产品推荐

