检查重叠的TimeField范围

时间:2019-01-12 17:18:48

标签: python-2.7 django-1.11

我有这个模型:

class Task(models.Model):
    class Meta:
        unique_together = ("campaign_id", "task_start", "task_end", "task_day")

    campaign_id = models.ForeignKey(Campaign, on_delete=models.DO_NOTHING)
    playlist_id = models.ForeignKey(PlayList, on_delete=models.DO_NOTHING)
    task_id = models.AutoField(primary_key=True, auto_created=True)
    task_start = models.TimeField()
    task_end = models.TimeField()
    task_day = models.TextField()

我需要编写一个验证测试,以检查新创建的任务时间范围是否与数据库中的现有任务时间范围重叠。

例如:

ID为1的任务的开始时间为下午5:00,结束于星期六的下午5:15。在第一个任务的开始时间和结束时间之间无法创建新任务。我应该在哪里编写此测试,最有效的方法是什么?我还使用DjangoRestFramework序列化程序。

2 个答案:

答案 0 :(得分:0)

当您从用户那里收到表单数据时,您可以:

  • 检查字段是否一致:用户 task_start <用户 task_end ,如果没有,则警告用户。
  • 查询(选择)数据库以检索所有现有的拦截用户时间的任务,

    • 通过 task_start (ORDER BY)排序记录,
    • 仅选择验证您的条件的记录,也就是:

      • task_start <=用户 task_start <= task_end ,或者
      • task_start <=用户 task_end <= task_end
    • 如果找到至少一条记录,则警告用户。

  • 一切正常:

    • 构造一个Task实例,

    • 将其存储在数据库中。

    • 返回成功。

实施细节:

可以在数据库中为

task_start task_end 建立索引,以缩短选择时间。

我看到您还有一个 task_day 字段(是TEXT)。

您应该真正考虑使用UTC DATETIME字段而不是TEXT,因为您需要比较日期和时间(不仅是时间):考虑一个从23:30开始并在第二天的00:45完成的任务... < / p>

答案 1 :(得分:0)

这就是我解决的方法。到目前为止,它并不是最佳选择,但是我仅限于python 2.7和Django 1.11,而且我还是一个初学者。

def validate(self, data):
    errors = {}
    task_start = data.get('task_start')
    task_end = data.get('task_end')
    time_filter = Q(task_start__range=[task_start, task_end]) 
    | Q(task_end__range=[task_start, task_end])
    filter_check = Task.objects.filter(time_filter).exists()
    if task_start > task_end:
        errors['error'] = u'End time cannot be earlier than start time!'
        raise serializers.ValidationError(errors)
    elif filter_check:
        errors['errors'] = u'Overlapping tasks'
        raise serializers.ValidationError(errors)
    else:
        pass
    return data