如何在Django中将@classmethod作为Celery任务运行?附示例代码
如何在Django中将@classmethod作为Celery任务运行?
刚好之前处理过类似的需求,这里分享两种可行的方案,结合你的示例代码来讲解:
方案一:直接给类方法添加Celery任务装饰器
Celery的任务装饰器可以直接作用在@classmethod上,只需要注意调用方式是通过类而非实例来触发异步任务。
修改后的示例代码:
首先确保你已经在Django项目中配置好了Celery(比如在项目根目录的celery.py中初始化了Celery app),然后修改Notification类:
from celery import app # 导入你配置好的Celery app from django.db import models from yourapp import constants from yourapp import settings class Notification(TimeStampedModel): # 你的模型字段定义... @classmethod @app.task # 这里添加Celery任务装饰器 def send_sms(cls, message, phone, user_obj=None, test=False): send_message(frm=settings.NEXMO_FROM_NUMBER, to=phone, text=message) return cls.objects.create( user=user_obj, email="", phone=phone, text_plain=message, notification_type=constants.NOTIFICATION_TYPE_SMS, sent=True, )
调用异步任务:
不再需要创建实例,直接通过类调用delay()方法触发异步执行:
# 基础异步调用 Notification.send_sms.delay(message='test', phone='1512351235') # 如果需要传递用户对象,注意Celery无法直接序列化Django模型实例,建议传递主键后在任务内查询 # 先修改send_sms方法适配参数: # @classmethod # @app.task # def send_sms(cls, message, phone, user_obj_id=None, test=False): # user_obj = User.objects.get(id=user_obj_id) if user_obj_id else None # # 后续逻辑不变 # 调用时传递用户ID Notification.send_sms.delay( message='test', phone='1512351235', user_obj_id=request.user.id )
方案二:包装成独立的Celery任务函数
如果不想修改原类的方法(比如原方法需要保持同步调用的能力),可以写一个单独的Celery任务函数,在内部调用类方法:
from celery import app from yourapp.models import Notification, User @app.task def send_sms_task(message, phone, user_obj_id=None, test=False): # 传递主键而非模型实例,避免序列化问题 user_obj = User.objects.get(id=user_obj_id) if user_obj_id else None return Notification.send_sms(message, phone, user_obj, test)
调用方式:
send_sms_task.delay(message='test', phone='1512351235', user_obj_id=1)
关键注意事项
- 序列化问题:Celery默认的序列化器无法直接处理Django模型实例,所以不要把模型对象作为任务参数,建议传递主键、ID等可序列化的值,在任务内部重新查询对象。
- Celery Worker配置:确保你的Celery Worker启动时加载了Django的配置,通常在
celery.py中已经通过os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yourproject.settings')完成配置。 - 同步/异步兼容:如果原类方法还需要同步调用,方案二更合适;如果只需要异步执行,方案一更简洁。
内容的提问来源于stack exchange,提问作者dev fan
相关产品推荐
相关产品推荐

