2016-11-05 106 views
0

在我的项目中,用户可以为他们的每个项目设置行动计划。例如,每周凌晨1点,凌晨2点或每周一和周三下午3点,6点和9点,可以执行此操作。所以,形式可以是这样的:在Django数据库中存储每周/每日安排

enter image description here

为了腾出资源,最小时间为小时,所以我可以运行芹菜任务,每隔一小时检查所有日程安排,看看它现在要做的一个动作。

我想弄清楚什么是最好的方式来存储这样的时间表在数据库中,以及如何使这样的模型。

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

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

模型调度器 - 每个产品都有它自己的对象

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) 

任务将其称之为每小时

@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) 

正如你可以看到有两个问题。这种模式不能为不同的日子设置不同的时间,而根据性能,在调度器中存储这些数据的方式可能不是最好的。你知道如何更好地将这些数据存储在模型中吗?

回答

2

为什么不在一个小时内使用一个Integer字段,以及一个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> 
相关问题