【发布时间】:2018-08-13 11:16:36
【问题描述】:
我正在尝试学习如何使用 celery 在我的一个模型上每天检查日期。我的一个模型包含一个到期日期和一个布尔字段,表示他们的保险是否过期。
模型很大,所以我要发布一个精简版。我想我有两个选择。要么在模型方法上运行 celery 任务,要么在我的 tasks.py 中重写函数。然后我需要使用 Celery beat 来运行计划以每天检查。
我的函数可以工作,但我直接传入模型对象,我认为这是错误的。
我在如何使用 celery.py 中的 celery beat 调度程序中的 args 时也遇到了麻烦。
我真的很接近让它工作,但我认为我正在以错误的方式执行任务。而且我认为在模型方法上执行任务可能是最干净的,我只是不确定如何完成。
models.py
class CarrierCompany(models.Model):
name = models.CharField(max_length=255, unique=True)
insurance_expiration = models.DateTimeField(null=True)
insurance_active = models.BooleanField()
def insurance_expiration_check(self):
if self.insurance_expiration > datetime.today().date():
self.insurance_active = True
self.save()
print("Insurance Active")
else:
self.insurance_active = False
self.save()
print("Insurance Inactive")
tasks.py
from __future__ import absolute_import, unicode_literals
from celery.decorators import task
from datetime import datetime, date
from django.utils import timezone
from .models import CarrierCompany
@task(name="insurance_expired")
def insurance_date():
carriers = CarrierCompany.objects.all()
for carrier in carriers:
date = datetime.now(timezone.utc)
if carrier.insurance_expiration > date:
carrier.insurance_active = True
carrier.save()
print("Insurance Active")
else:
carrier.insurance_active = False
carrier.save()
print("Insurance Inactive")
芹菜.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from celery.schedules import crontab
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local')
app = Celery('POTRTMS')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
app.conf.beat_schedule = {
'check-insurance-daily': {
'task': 'insurance_expired',
'schedule': crontab(hour='8')
},
}
*** 更新了节拍时间表以反映我真正想要运行它的时间。
【问题讨论】:
-
哇,我使用了错误的设置文件,所以我的任务无法访问数据库。我已经解决了这个问题,我正在这里更新我的代码。我仍然认为我称我的模型对象是错误的。
-
嘿,我明白了,你想将运营商传递给函数吗? Bc 你让它得到里面的对象,这很好,所以不需要向函数传递任何值。另外,我会使用 celery-beat bc,它很容易设置并且可以正常工作。在模型中,如果您将该函数定义为属性,则在循环运营商时,您可以调用运营商.insurance_expiration_check。如果我在正轨上,我可以给出更深入的答案,或者如果你想走另一条路,我也可以尝试并提供帮助......
-
@CoolestNerdIII 哎呀,是的,你肯定走在正确的轨道上。我已经删除了将“运营商”传递到函数中,现在可以按预期工作。 1. 现在我的问题是,在使用 celery 时将这样的模型对象传递给函数是否可以,听起来可以。 2. 第二部分听起来是编写代码的更好方法。在模型中调用它。这就是我真正迷失芹菜和芹菜节拍的地方。
-
我想我以为我已经在使用 celery-beat,方法是在我的 celery.py 中使用 app.conf.beat_schedule
-
我可能只需要举一个例子来回答,但是这样称呼它很好。如果您调用该函数并传递一个对象而不是一个 ID,就会出现问题(您现在什么都不传递,所以您很好)。我将在答案中举一个例子,因为这里没有足够的空间。
标签: django celery celery-task celerybeat