检查重叠的 TimeField 范围

Checking for overlapping TimeField ranges

我有这个型号:

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:00PM,结束时间为星期六 5:15PM。不能在第一个任务的开始和结束时间之间创建新任务。我应该在哪里编写这个测试,最有效的方法是什么?我也使用 DjangoRestFramework 序列化程序。

当您收到用户的表单数据时,您可以:

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

    • task_start (ORDER BY),
    • 对记录进行排序
    • Select 仅记录验证您的标准,a.k.a.:

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

  • 一切正常:

    • 构造一个Task实例,

    • 存入数据库

    • Return成功。

实施细节:

task_starttask_end 可以在您的数据库中建立索引以缩短选择时间。

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

您真的应该考虑使用 UTC DATETIME 字段而不是 TEXT,因为您需要比较日期和时间(而不仅仅是时间):考虑一个从 23:30 开始并在 [=90= 结束的任务] 后一天……

我就是这样解决的。到目前为止还不是最优的,但我仅限于 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