You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:46:58