Django生产环境(DEBUG=False)下Celery邮件任务启动失败求助
首先,咱们拆解你遇到的核心错误:TypeError("enviar_documentos_async() got an unexpected keyword argument 'cliente'",)——这说明你的任务函数收到了一个未定义的参数cliente,但代码里明明传的是client,而且DEBUG模式下完全正常。结合你的代码和环境,我整理了几个最可能的原因和解决步骤:
1. 最容易忽略的问题:任务调用缺少必填参数documents
你的任务函数enviar_documentos_async把documents作为第三个必填参数,但在触发函数send_documents里,你明明接收了documents参数,却完全没传给任务!虽然错误提示看起来是参数名的问题,但参数缺失可能打乱Celery的参数解析逻辑,引发奇怪的异常。
修改触发代码,补上这个必填参数:
def send_documents(company, client, documents, type, template="invoice", context=None): # 别用和函数名相同的变量名,会覆盖函数本身的引用! send_task = send_documents_async.delay send_task( company=company.pk, client=client.pk, documents=documents, # 必须添加这个参数 type=type, template=template, context=context )
2. 参数名不匹配:client vs cliente
错误里的cliente是西班牙语的“客户”,而你代码里用的是英文client,大概率是以下两种情况:
- 代码拼写错误:仔细检查所有触发该任务的地方,有没有误把
client=xxx写成cliente=xxx;同时确认任务函数的参数名确实是client,而非cliente。 - Celery Worker加载了旧代码:生产环境下Celery Worker不会像DEBUG模式那样自动重载代码,如果你最近修改过任务函数的参数名,必须重启Worker才能加载新代码:
# 先终止旧的Worker进程 ps aux | grep celery | grep -v grep | awk '{print $2}' | xargs kill # 启动新的Worker celery worker -A invoice2 --loglevel=info
3. 任务导入与调用的名称不匹配
你的触发代码导入的是from notifications.tasks import send_async_documents,但调用的却是send_documents_async.delay——这明显是名称写错了!如果实际代码真的是这样,DEBUG模式下也会报错,大概率是你写代码时的笔误,修正导入:
from notifications.tasks import send_documents_async # 导入正确的任务函数 def send_documents(company, client, documents, type, template="invoice", context=None): send_task = send_documents_async.delay send_task( company=company.pk, client=client.pk, documents=documents, type=type, template=template, context=context )
4. 任务名称注册异常
你给任务装饰器设置了name="send_documents",但错误信息里的任务却是enviar_documentos,说明Celery可能没有使用你指定的名称,而是自动生成了基于函数名的变体。建议直接用导入的任务对象调用,而非依赖任务名称,这样更可靠。
5. 序列化器配置问题
DEBUG模式和生产环境下,Celery的序列化器可能存在差异,导致参数解析异常。在settings.py里明确指定序列化器:
# Celery序列化配置 CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json'
优先从第1、2点开始排查,这两个是最常见的原因,应该能快速解决你的问题。
内容的提问来源于stack exchange,提问作者Diego Peñalver Montero

