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

在Django+DRF的CreateAPIView中配置Celery实现延迟任务

问题描述

我已经为Django项目配置了Celery处理后台任务,但创建Event时,无法实现后台60秒睡眠延迟且不阻塞请求。相关代码如下:

models.py

class Event(models.Model):
    # Fields description

    def __str__(self) -> str:
        return self.title

    class Meta():
        verbose_name = 'Мероприятие'
        verbose_name_plural = 'Мероприятия'

serializers.py

class EventCreateSerializer(serializers.ModelSerializer):
    organizations = serializers.PrimaryKeyRelatedField(
        queryset=Organization.objects.all(),
        many=True,
        required=True
    )

    class Meta:
        model = Event
        fields = ('title', 'description', 'organizations', 'date', 'image')

views.py

class EventCreateView(CreateAPIView):
    """
    创建新的活动。
    """
    serializer_class = EventCreateSerializer
    queryset = Event.objects.all()
    # permission_classes = [IsAuthenticated,]

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

tasks.py

from celery import shared_task
from time import sleep
from .models import Event

@shared_task
def async_task(event_id):
    sleep(60)
    event = Event.objects.get(pk=event_id)
    print(f'Async task completed for event with ID {event_id}')

目前EventCreateView能正常运行,但任务似乎会立即执行,对象创建时没有预期的延迟。需要做哪些修改才能正确实现60秒的睡眠延迟?


解决方案

问题核心是你没有触发Celery异步任务——当前仅定义了任务,但未在Event创建后将任务提交到Celery队列。按以下步骤修改:

1. 在views.py中导入并调用Celery任务

修改EventCreateView,重写perform_create方法,在Event保存后提交异步任务:

from .tasks import async_task  # 导入任务

class EventCreateView(CreateAPIView):
    """
    创建新的活动。
    """
    serializer_class = EventCreateSerializer
    queryset = Event.objects.all()
    # permission_classes = [IsAuthenticated,]

    def perform_create(self, serializer):
        # 先保存Event对象到数据库
        event = serializer.save()
        # 用delay()提交任务到Celery队列,而非直接调用async_task(event.id)
        async_task.delay(event.id)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

2. 关键注意点

  • 必须使用async_task.delay(event.id):直接调用async_task(event.id)会在当前请求线程执行,导致请求阻塞;delay()会将任务发送到Celery队列,由后台worker异步执行。
  • 确保Celery Worker正在运行:在项目根目录执行启动命令:
celery -A 你的项目名称 worker --loglevel=info

3. 验证Celery配置正确性

检查settings.py中的Celery broker配置(以Redis为例):

CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'

内容的提问来源于stack exchange,提问作者Kichkinev Vladislav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:50:14