Django 日历 空闲/忙碌/可用性

12 投票
2 回答
4120 浏览
提问于 2025-04-15 19:20

我正在尝试实现一个日历系统,能够为其他人安排约会。这个系统必须能够防止在某个人已经有其他约会或在他们不方便的时间内安排新的约会。

我查看了网上找到的所有现有的django日历项目,但似乎没有一个是内置这个功能的(如果我错过了什么,请告诉我)。

也许我只是有点累了,但我想到的唯一方法似乎有点麻烦。下面是我想到的伪代码:

  • 当用户尝试创建一个新约会时,获取这个新约会的开始时间和结束时间
  • 对于同一天的每个约会,检查是否有以下情况
    • 已有的开始时间小于新约会的开始时间,并且已有的结束时间大于新约会的开始时间(新约会的开始时间是否在任何已有约会的开始和结束时间之间)
    • 已有的开始时间小于新约会的结束时间,并且已有的结束时间大于新约会的结束时间(新约会的结束时间是否在任何已有约会的开始和结束时间之间)
  • 如果没有找到冲突的约会,那么就可以添加这个新约会

考虑到Django没有基于时间的过滤,这一切都必须通过在查询集中使用.extra()来完成。

所以,我在问是否有更好的方法。有没有什么Python的小技巧或模块,或者任何可以简化这个过程的东西,或者有没有现有的项目可以满足我的需求,或者能指引我找到正确的方向。

谢谢。

2 个回答

0

这里有一个需要注意的地方,就是不同用户可能在不同的时区。而且如果再加上夏令时的问题,事情就变得非常复杂了。

你可能想了解一下pytz这个模块,它可以帮助你处理时区的问题。

16

可以考虑使用Django的范围测试

比如说:

appoinment = Appointment()
appointment.start_time = datetime.datetime.now()
# 1 hour appointment
appointment.end_time = appointment.start_time + datetime.timedelta(hours=1)
# more stuff here
appointment.save()

# Checking for collision
# where the start time for an appointment is between the the start and end times
# You would want to filter this on user, etc 
# There is also a problem if you book an appointment within another appointment
start_conflict = Appointment.objects.filter(
                     start_time__range=(appointment.start_time,
                                        appointment.end_time))
end_conflict = Appointment.objects.filter(
                   end_time__range=(appointment.start_time,
                                    appointment.end_time))

during_conflict = Appointment.objects.filter(
                      start_date__lte=appointment.start_time, 
                      end_date__gte=appointment.end_time)

if (start_conflict or end_conflict or during_conflict):
    # reject, for there is a conflict

这样可以吗?我自己还没试过,所以你可能需要稍微调整一下。

编辑:我加上了during_conflict的部分。

撰写回答