Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django calendar free/busy/availabilitty

I am trying to implement a calendar system with the ability to schedule other people for appointments. The system has to be able to prevent scheduling a person during another appointment or during their unavailable time.

I have looked at all the existing django calendar projects I have found on the internet and none of them seem to have this built-into them (if I missed it somehow, please let me know).

Perhaps I am just getting too tired, but the only way I can think of doing this seems a little messy. Here goes in pseudo code:

  • when a user tries to create a new appointment, grab the new appointment's start_time and end_time
  • for each appointment on that same day, check if
    • existing_start_time < new_start_time AND existing_end_time > new_start_time (is the new appointments start time in between any existing appointment's start and end times)
    • existing_start_time < new_end_time AND existing_end_time > new_end_time (is the new appointments end time in between any existing appointment's start and end times)
  • if no objects were found, then go ahead and add the new appointment

Considering Django has no filtering based on time, this must all be done using .extra() on the queryset.

So, I am asking if there is a better way. A pythonic trick or module or anything that might simplify this. Or an existing project that has what I need or can lead me in the right direction.

Thanks.

like image 921
mhost Avatar asked Feb 16 '10 07:02

mhost


1 Answers

What about using Django's range test.

For example:

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

Something like that? I haven't tried this myself so you may have to tweak it a bit.

EDIT: Added the during_conflict bit.

like image 159
Nick Presta Avatar answered Sep 30 '22 00:09

Nick Presta