允许Celery.py时的警告提示

PeriodicTask.last_run_at received a naive datetime (2024-05-19 06:33:20.983919) while time zone support is active.

警告原因:

问题出在Django的时区支持是活动的(ACTIVE),但是收到的是一个"naive"(不含时区信息)的日期时间对象。

在Django中,对于日期时间的处理,它区分为"aware"(包含时区信息)和"naive"(不包含时区信息)两种日期时间对象。

代码调整

你可以在Django的设置文件settings.py中设置使用的时区TIME_ZONE以及是否开启时区支持USE_TZ。例如:

TIME_ZONE = 'UTC'
USE_TZ = True

在Django-Celery中,所有的日期时间信息应为"aware"对象。

所以,一种处理方式是确保你创建的所有Datetime对象都是aware的。在创建Datetime对象的时候,最好利用Django提供的timezone模块,而不是直接用Python的datetime模块。像下面这样:

from django.utils import timezone
current_time = timezone.now()

上述方法创建的current_time就是一个aware的日期时间对象。

如果你在Celery中定义的定时任务是用的Python的datetime模块创建的naive的日期时间对象,你需要修改为Django的timezone模块来创建。

如果你在Django的配置中已经设置了 USE_TZ = True,那么在你的celery.py文件中,请确保你有以下这行代码:

from django.conf import settings
app.conf.enable_utc = settings.USE_TZ

这样可以确保Celery会使用和Django相同的设置来处理时区问题。

如果你有任务计划CELERY_BEAT_SCHEDULE在你的celery.py文件里,那么你可以使用Django设置的时区。celery.schedule.crontab和celery.schedule.timedelta是用来设置定时任务的,分别用于定时执行和周期执行的任务。

from datetime import timedelta
from celery.schedules import crontab
from django.utils import timezone

app.conf.beat_schedule = {
'task1': {
'task': 'your_project.tasks.your_task1',
'schedule': crontab(minute=0, hour='2,6', day_of_week='1', nowfun=timezone.now),
},

'task2': {
'task': 'your_project.tasks.your_task2',
'schedule': timedelta(hours=1),
},
}

在 schedule': crontab(minute=0, hour='2,6', day_of_week='1', nowfun=timezone.now), 中nowfun=timezone.now 保证了任务会根据Django的时区设置来执行。如果day_of_week='1',那么这个任务会在每周一的第2和第6个小时开始。

'schedule': timedelta(hours=1)配置表示您的任务将每隔1小时运行一次。

需要注意的是,task的路径应该是从你的项目名称开始的全路径,就像从你的测试文件开始的那样。另外,请确保你已经在你的__init__.py中导入了celery.py来启动你的celery worker 和 celery beat。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐