在Django数据库中存储每周/每日调度

时间:2016-11-05 12:01:58

标签: django django-models

在我的项目中,用户可以为每个项目设置行动计划。该动作可以例如每周一次,每天凌晨1点,每天凌晨2点或每周一和周三下午3点,下午6点和上午9点进行。因此表单可能如下所示:

enter image description here

为了节省资源,最小时间是小时,所以我可以运行芹菜任务,每小时检查一次所有时间表并查明是否必须立即采取行动。

我正在试图弄清楚在数据库中存储此类计划的最佳方法是什么以及如何制作这样的模型。

我要做的第一件事就是以字符串格式为每个产品存储类似芹菜cron标签的内容 - 'x x x x x' - 例如"hour='3,17,22', day_of_week='thu,fri'"。但我认为这很糟糕,因为我必须每小时解析每个字符串,这非常耗时。

最后,我做了7列的模型 - 天和24列小时。有两个问题 - 它可能不是存储此类时间表的最佳方式,第二个问题是每个(真)日都设置了我不想要的相同时间。

MODEL SCHEDULER - 每件产品都有自己的对象

class Scheduler(models.Model):
    monday = models.BooleanField(default=False)
    tuesday = models.BooleanField(default=False)
    wednesday = models.BooleanField(default=False)
    thursday = models.BooleanField(default=False)
    friday = models.BooleanField(default=False)
    saturday = models.BooleanField(default=False)
    sunday = models.BooleanField(default=False)

    hour_1 = models.BooleanField(default=False)
    hour_2 = models.BooleanField(default=False)
    hour_3 = models.BooleanField(default=False)
    hour_4 = models.BooleanField(default=False)
    hour_5 = models.BooleanField(default=False)
    hour_6 = models.BooleanField(default=False)
    hour_7 = models.BooleanField(default=False)
    hour_8 = models.BooleanField(default=False)
    hour_9 = models.BooleanField(default=False)
    hour_10 = models.BooleanField(default=False)
    hour_11 = models.BooleanField(default=False)
    hour_12 = models.BooleanField(default=False)
    hour_13 = models.BooleanField(default=False)
    hour_14 = models.BooleanField(default=False)
    hour_15 = models.BooleanField(default=False)
    hour_16 = models.BooleanField(default=False)
    hour_17 = models.BooleanField(default=False)
    hour_18 = models.BooleanField(default=False)
    hour_19 = models.BooleanField(default=False)
    hour_20 = models.BooleanField(default=False)
    hour_21 = models.BooleanField(default=False)
    hour_22 = models.BooleanField(default=False)
    hour_23 = models.BooleanField(default=False)
    hour_24 = models.BooleanField(default=False)

TASK ,每小时都会调用

@app.task()
def check_for_actions():
    day = datetime.today().weekday()
    hour = datetime.now().hour

    # get all schedulers for this day
    if day==0:
        scheduled_this_day = models.Scheduler.objects.filter(monday=True)
    elif day==1:
        scheduled_this_day = models.Scheduler.objects.filter(tuesday=True)
    elif day==1:
        scheduled_this_day = models.Scheduler.objects.filter(wednesday=True)
    elif day==1:
        scheduled_this_day = models.Scheduler.objects.filter(thursday=True)
    elif day==1:
        scheduled_this_day = models.Scheduler.objects.filter(friday=True)
    elif day==1:
        scheduled_this_day = models.Scheduler.objects.filter(saturday=True)
    elif day==1:
        scheduled_this_day = models.Scheduler.objects.filter(sunday=True)

    #filter schedulers for this hour
    if hour==1:
        scheduled_this_hour = scheduled_this_day.filter(hour_1=True)
    elif hour==2:
        ...

    for product in [x.product for x in scheduled_this_hour]:
        do_action(product)

正如您所看到的,有两个问题。此模型不能为不同日期设置不同的小时数,并且根据性能,在Scheduler中存储此类数据的方式可能不是最好的。你知道如何更好地在模型中存储这些数据吗?

1 个答案:

答案 0 :(得分:3)

为什么不在一小时内使用一个整数字段,为一周中的某一天选择一个CharField?

from django.core.validators import MaxValueValidator

class Scheduler(models.Model):
        day_of_week = models.CharField(default='Monday', 
                                      choices=(('monday', 'Monday'), ('tuesday', 'Tuesday')...))
        hour = models.PositiveSmallIntegerField(validators=[MaxValueValidator(24)])

芹菜:

# I prefer arrow for formatting dates/times
import arrow

@app.task()
def check_for_actions():
    weekday = arrow.utcnow().format('dddd') # Monday, Tuesday, etc
    hour = datetime.now().hour

    scheduled = models.Scheduler.objects.filter(day_of_week=weekday).filter(hour=hour)

至于

  

此模型不能为不同日期设置不同的小时数

这个模型不能,但它可以与您调度的任何内容建立关系。

class Scheduler(models.Model):
        thing_to_schedule = models.ForeignKey('ThingToSchedule')
        day_of_week = models.CharField(default='Monday', 
                                          choices=(('monday', 'Monday'), ('tuesday', 'Tuesday')...))
        hour = models.PositiveSmallIntegerField(validators=[MaxValueValidator(24)])

然后ThingToSchedule有一个所有需要运行的时间表集。

schedules = ThingToSchedule.schedule_set.all()
<Monday at 3>, <Tuesday at 6>