You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何检查时间段重叠,避免Slot模型时段冲突

实现方案

核心判断逻辑

两个时段[start1, end1)和[start2, end2)重叠的充要条件是 start1 < end2 AND start2 < end1,你的需求里时段端点相等(如end1 = start2)属于合法不重叠场景,正好符合该判断规则。

完整代码实现

我们直接在Django模型层添加校验逻辑,覆盖所有写入场景的校验需求:

from django.db import models
from django.core.exceptions import ValidationError
from django.db.models import Q

class Slot(models.Model):
    start_time = models.TimeField()
    end_time = models.TimeField()

    def clean(self):
        # 基础校验:确保开始时间早于结束时间
        if self.start_time >= self.end_time:
            raise ValidationError("结束时间必须晚于开始时间")
        
        # 重叠时段查询
        overlapping_slots = Slot.objects.filter(
            Q(start_time__lt=self.end_time) & Q(end_time__gt=self.start_time)
        ).exclude(pk=self.pk) # 排除当前正在编辑的记录,避免更新时自己和自己冲突

        if overlapping_slots.exists():
            raise ValidationError("该时段与已有时段重叠,无法保存")

    def save(self, *args, **kwargs):
        # 保存前自动触发校验,无需手动调用full_clean
        self.full_clean()
        super().save(*args, **kwargs)

逻辑验证

以你举的例子测试:

  • 已存在时段02:00:00 - 03:00:00
  • 新增01:00:00 - 02:00:00:已有记录的start_time=02:00:00不小于当前end_time=02:00:00,查询不到重叠记录,校验通过
  • 新增03:00:00 - 04:00:00:已有记录的end_time=03:00:00不大于当前start_time=03:00:00,查询不到重叠记录,校验通过
  • 新增02:30:00 - 03:30:00:可以查询到重叠记录,校验失败抛出异常

扩展说明

如果业务存在多维度隔离规则(比如不同日期、不同会议室的时段互不影响),只需要在filter查询中添加对应的维度过滤条件即可,示例:

# 假设模型新增了date、room_id字段,仅校验同日期同会议室的时段重叠
overlapping_slots = Slot.objects.filter(
    date=self.date,
    room_id=self.room_id,
    Q(start_time__lt=self.end_time) & Q(end_time__gt=self.start_time)
).exclude(pk=self.pk)

内容的提问来源于stack exchange,提问作者raj-kapil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:09:03