2010-02-16 10 views
8

Sto cercando di implementare un sistema di calendario con la possibilità di pianificare altre persone per gli appuntamenti. Il sistema deve essere in grado di impedire la pianificazione di una persona durante un altro appuntamento o durante il tempo non disponibile.django calendar free/busy/availabilitty

Ho esaminato tutti i progetti di calendario di django che ho trovato su Internet e nessuno di loro sembra averli incorporati (se l'ho perso in qualche modo, fatemelo sapere).

Forse sto diventando troppo stanco, ma l'unico modo in cui posso pensare di farlo sembra un po 'confuso. Qui va in pseudo-codice:

  • quando un utente tenta di creare un nuovo appuntamento, afferrare start_time della nuova nomina e END_TIME
  • per ogni appuntamento in quello stesso giorno, controllare se
    • existing_start_time < new_start_time AND existing_end_time> new_start_time (è l'ora di inizio dei nuovi appuntamenti tra qualsiasi ora di inizio e di fine di un appuntamento esistente)
    • time_start_time < new_end_time AND existing_end_time> new_end_time (è i nuovi appuntamenti it tempo d tra inizio e fine di ogni appuntamento esistente)
  • se non sono stati trovati oggetti, poi andare avanti e aggiungere il nuovo appuntamento

Considerando Django non ha alcun filtraggio in base al tempo, tutto questo deve essere fatto usando .extra() sul queryset.

Quindi, sto chiedendo se c'è un modo migliore. Un trucco o un modulo pitonico o qualsiasi cosa che possa semplificare questo. O un progetto esistente che ha ciò di cui ho bisogno o che può guidarmi nella giusta direzione.

Grazie.

risposta

13

Che dire dell'utilizzo di range test di Django.

Ad esempio:

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 

Qualcosa del genere? Non l'ho provato da solo, quindi potrebbe essere necessario modificarlo un po '.

MODIFICA: Aggiunto il during_conflict bit.

+1

+1 Impressionante! Non avevo visto il test dell'intervallo è stato incorporato nell'API QuerySet di Django. –

+0

Grazie per l'ottimo consiglio. Mancavano eventi che erano iniziati prima e terminati dopo il nuovo appuntamento. Ad esempio: se un cliente ha un appuntamento da 1 a 5, ciò non impedirebbe a qualcuno di prenotare da 2 a 3. Ho aggiunto quanto segue per includere tali situazioni: durante_conflict = Appointment.objects.filter (start_date__lte = appuntamento.start_time, end_date__gte = appuntamento.end_time) if (start_conflict o end_conflict o during_conflict): – mhost

+0

Eccellente. Sono contento che questo sia stato utile. Ho intenzione di aggiungere il tuo caso in modo che la risposta sia più completa. –

0

Un avvertimento qui è i diversi fusi orari di diversi utenti, e portare il tempo di risparmio Daylight nel mix le cose diventano molto complicate.

Si potrebbe voler dare un'occhiata a pytz modulo per prendersi cura del problema del fuso orario.