2010-02-16 17 views
8

Estoy tratando de implementar un sistema de calendario con la capacidad de programar citas para otras personas. El sistema debe poder evitar programar a una persona durante otra cita o durante el tiempo no disponible.django calendar free/busy/availabilitty

He examinado todos los proyectos existentes de calendarios django que he encontrado en Internet y ninguno parece tenerlos incorporados (si me lo hubiera perdido de alguna manera, por favor, avíseme).

Tal vez estoy demasiado cansado, pero la única forma en que puedo pensar en hacer esto parece un poco desordenado. Aquí va en pseudo código:

  • cuando un usuario intenta crear una nueva cita, agarra hora_inicial de la nueva cita y hora_final
  • para cada cita en ese mismo día, comprobar si
    • existing_start_time < new_start_time Y existing_end_time> new_start_time (es la hora de inicio de las nuevas citas entre las horas de inicio y finalización de cualquier cita existente)
    • existing_start_time < new_end_time AND existing_end_time> new_end_time (es las nuevas citas es d tiempo en entre los tiempos de inicio y fin de cualquier cita existente)
  • si no se encuentran los objetos, y luego seguir adelante y añadir la nueva cita

Considerando Django tiene ningún filtrado basado en el tiempo, todo esto debe hacerse usando .extra() en el conjunto de preguntas.

Entonces, estoy preguntando si hay una manera mejor. Un truco o módulo pitónico o cualquier cosa que pueda simplificar esto. O un proyecto existente que tiene lo que necesito o puede llevarme en la dirección correcta.

Gracias.

Respuesta

13

¿Qué hay de usar Django's range test.

Por ejemplo:

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 

Algo por el estilo? No lo he intentado yo mismo, así que quizás tengas que modificarlo un poco.

EDITAR: Agregó during_conflict bit.

+1

+1 ¡Impresionante! No había visto la prueba de rango integrada en la API QuerySet de Django. –

+0

Gracias por el gran consejo. Faltan eventos que comenzaron antes y terminaron después de la nueva cita. Por ejemplo: si un cliente tenía una cita del 1 al 5, esto no evitaría que alguien reservara del 2 al 3. Agregué lo siguiente para incluir tales situaciones: during_conflict = Appointment.objects.filter (start_date__lte = appointment.start_time, end_date__gte = cita.end_time) if (start_conflict o end_conflict o during_conflict): – mhost

+0

Excelente. Me alegro de que esto haya sido útil. Voy a agregar tu caso para que la respuesta sea más completa. –

0

Una advertencia aquí es las diferentes zonas horarias de los diferentes usuarios, y llevar el horario de verano a la mezcla, las cosas se vuelven muy complicadas.

Es posible que desee echar un vistazo a pytz módulo para ocuparse del problema de la zona horaria.

Cuestiones relacionadas