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

如何用Celery实现定时删除过期对象?当前24小时清理任务未执行

问题解决与实现方案

先搞定你的定时删除24小时文件无效问题

你的代码里有几个明显错误,还有些配置得确认:

1. 过滤条件完全写错了

你现在的delete_file任务里,过滤的是所有上传时间早于现在的文件,这肯定不是你要的24小时前的效果。改一下tasks.py里的逻辑:

from datetime import timedelta
from django.utils import timezone
from celery import shared_task
from .models import Archivo

@shared_task
def delete_file():
    # 算出24小时前的时间点
    cutoff_time = timezone.now() - timedelta(hours=24)
    # 只删上传时间早于这个点的文件
    files = Archivo.objects.filter(fecha_subida__lte=cutoff_time)
    if files.exists():
        deleted_count, _ = files.delete()
        return f"已删 {deleted_count} 个文件"
    return "没找到符合条件的文件"

2. 一定要启动Celery Beat进程

定时任务是靠Celery Beat调度的,光启动worker没用,得同时开beat:

# 先启动worker
celery -A arhi worker -l info
# 新开个终端启动beat
celery -A arhi beat -l info

生产环境里建议用supervisor或者systemd管理这俩进程,别关了终端就停了。

3. 确认任务路径和APP配置

检查beat_schedule里的任务路径tarea.tasks.delete_file:

  • 确保你的Django app名字真的是tarea,而且settings.py的INSTALLED_APPS里加了tarea
  • 要么确认autodiscover_tasks()能找到这个任务,要么手动指定:app.autodiscover_tasks(['tarea'])

4. 时区得一致

Django的settings.py里的TIME_ZONE必须和Celery的timezone一样:

# settings.py
TIME_ZONE = 'America/Bogota'

时区不一样的话,时间计算会出错,明明到24小时了也删不了。

5. 看日志找问题

启动worker和beat的时候加-l info日志级别,看看有没有任务执行的记录,有没有报错。比如worker日志里要是出现任务找不到、数据库连不上,就能立刻定位问题。


实现对象5分钟后自动删的两种办法

要是想实现单个文件上传后5分钟就删,不用每分钟轮询数据库,有俩更高效的方式:

方案1:用countdown延迟执行任务

创建Archivo对象的时候,直接调用删除任务并设5分钟延迟:

# 在创建文件的视图或者信号里写
from tarea.tasks import delete_single_file

# 创建完对象后
archivo = Archivo.objects.create(file="你的文件名")
# 300秒=5分钟后执行删除
delete_single_file.apply_async(args=[archivo.id], countdown=300)

对应的tasks.py要加单个删除的任务:

@shared_task
def delete_single_file(archivo_id):
    try:
        archivo = Archivo.objects.get(id=archivo_id)
        archivo.delete()
        return f"已删文件 {archivo_id}"
    except Archivo.DoesNotExist:
        return f"文件 {archivo_id} 不存在"

方案2:用ETA指定执行时间

和countdown类似,不过是直接指定具体执行时间:

from datetime import timedelta

eta_time = timezone.now() + timedelta(minutes=5)
delete_single_file.apply_async(args=[archivo.id], eta=eta_time)

这种方式比定时轮询省资源,不用每次查一堆数据,精准触发单个文件的删除。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:15:33