Django 1.11.5集成Celery 4传递用户时遇ValueError错误求助
解决Celery任务接收用户参数时的ValueError问题
这个错误很好定位——你的Celery任务task_number_one应该是在尝试把你传入的用户名字符串当作整数类型的用户ID来处理,所以才会抛出invalid literal for int() with base 10: 'my_username'的转换错误。
问题根源
你在视图里传递的是dict_obj['username'](字符串类型的用户名),但任务内部大概率写了类似User.objects.get(id=传入参数)的代码,试图把字符串转成整数ID,自然就触发了类型不匹配的错误。
另外要强调:Celery任务不能直接传递Django的用户对象(因为对象无法被序列化跨进程传递),所以业内通用的最佳实践是传递用户的主键ID,再在任务内部通过ID查询用户对象。
修复方案
方案1:传递用户ID(推荐)
修改视图里的form_valid方法,直接传递用户的主键ID:
def form_valid(self, form): form.instance.user = self.request.user # 传递用户ID而非用户名 task_number_one.delay(self.request.user.id) return super().form_valid(form)
然后同步修改Celery任务,通过ID查询用户对象:
from django.contrib.auth.models import User from celery import shared_task @shared_task def task_number_one(user_id): try: # 通过ID获取用户对象 user = User.objects.get(id=user_id) # 在这里执行你的任务逻辑,比如处理用户相关数据 except User.DoesNotExist: # 处理用户不存在的异常,比如记录日志 pass
方案2:若必须传递用户名
如果你业务上确实需要用用户名作为参数,那要修改任务内部的查询逻辑,按用户名查询用户:
@shared_task def task_number_one(username): try: user = User.objects.get(username=username) # 执行任务逻辑 except User.DoesNotExist: # 处理异常情况 pass
不过这种方式不如传ID可靠,因为用户名存在被修改的可能,而主键ID是永久不变的。
额外提示
在Celery任务中,永远不要直接传递Django模型对象或者请求对象——这类复杂对象无法被正确序列化传递到任务进程中。传递主键ID、用户名这类简单的可序列化数据是最稳妥的选择。
内容的提问来源于stack exchange,提问作者user9357277
相关产品推荐
相关产品推荐

