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

Django模型:字段元组过滤与无冲突课程查询实现问题

嘿,这个需求我之前做课表系统的时候刚好碰到过,咱们一步步拆解来解决哈!

首先得明确冲突的核心判定规则:两个课程只要满足「在同一天上课」并且「时间区间有重叠」,就算冲突。反过来,无冲突的课程要么完全不在同一天,要么同一天但时间完全不交叉。

1. 先搞定日期匹配的逻辑

你的日期字段是"MoTuWeThFr"这种字符串,每个两位字母代表星期几(Mo=周一、Tu=周二,以此类推)。首先得把这种字符串拆成单个星期几的集合,这样才能快速判断两个课程有没有共同的上课日。

写个简单的辅助函数来拆分:

def get_weekday_set(date_str):
    # 把连续的日期字符串拆成单个星期几的集合,比如"MoTuWe" → {"Mo", "Tu", "We"}
    return set([date_str[i:i+2] for i in range(0, len(date_str), 2)])

2. 再处理时间重叠的判断

时间重叠是个经典的区间问题:只要课程A的开始时间 < 课程B的结束时间,同时课程A的结束时间 > 课程B的开始时间,就说明两个时间区间有重叠。

假设你的时间字段是datetime.time类型,或者可以转换成分钟数(比如把"09:00"转成9*60=540),写个辅助函数:

def is_time_overlap(start1, end1, start2, end2):
    # 支持datetime.time或整数分钟数的比较
    return start1 < end2 and end1 > start2

3. 筛选无冲突课程的主逻辑

假设你有已添加课程列表enrolled_courses,现在要从所有课程all_courses里挑出无冲突的,直接循环判断就行:

def get_conflict_free_courses(all_courses, enrolled_courses):
    conflict_free_list = []
    for course in all_courses:
        course_days = get_weekday_set(course.days)
        course_start = course.start_time
        course_end = course.end_time
        
        # 标记当前课程是否和任意已添加课程冲突
        has_conflict = False
        for enrolled_course in enrolled_courses:
            enrolled_days = get_weekday_set(enrolled_course.days)
            # 先检查有没有共同的上课日
            if course_days & enrolled_days:
                # 有共同日期,再检查时间是否重叠
                if is_time_overlap(course_start, course_end, enrolled_course.start_time, enrolled_course.end_time):
                    has_conflict = True
                    break  # 只要冲突就不用再看其他已添加课程了
        
        if not has_conflict:
            conflict_free_list.append(course)
    return conflict_free_list

4. 可选的优化建议

如果课程数量特别多,上面的循环效率可能不够,可以试试这几个优化点:

  • 按星期分组已添加课程:把已添加课程按星期几分类(比如{"Mo": [周一的课程], "Tu": [周二的课程]}),这样筛选时只需要检查当前课程对应星期的已添加课程,不用遍历全部。
  • 时间转分钟数存储:把开始/结束时间转换成整数分钟数(比如09:00→540),比较起来比时间对象更快。
  • ORM层面筛选(如果用Django等框架):可以把日期不重叠的课程先通过数据库查询筛出来,剩下的再在内存里处理时间冲突,减少内存压力。比如用Django的Q查询排除包含已添加课程星期几的课程。

另外要注意:确保日期字符串的格式统一,比如有没有大小写差异(比如"mo"和"Mo"),如果有的话,处理前先统一转成大写或小写。

内容的提问来源于stack exchange,提问作者Jason Valladares

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:54:32