Django - Show date and time of appointment

I'm currently showing all dates that appointments are not booked.

from datetime import date, timedelta

num_days = 5
start_date = date.today()
timeframe = [start_date + timedelta(days=d) for d in range(num_days)]
exclude = list(Transaction.objects.values_list("start_appointment__date", flat=True).distinct())

set(timeframe) - set(exclude)

For example i have appointments booked for:

[datetime.date(2021, 12, 8), datetime.date(2021, 12, 7), datetime.date(2021, 12, 7), datetime.date(2021, 12, 7)]

And the dates not booked:

{datetime.date(2021, 12, 10), datetime.date(2021, 12, 9), datetime.date(2021, 12, 11)}

I would like to show also the available times for the not booked dates with a time interval between 11:00AM to 21:00PM:.

Is that possible with the current implementation? If yes how can i achieve that? If not could you please suggest an alternative way?

Thank you

It's hard to judge from the information provided.

  • What does the database models look like
  • What is an 'appointment'?
  • is 'Transaction' a set of 'appointments', or a set of time slots?
  • Assuming 'Transactions' is a set of time slots, how do you know whether they are booked? If you're using a boolean flag, why not filter for that one?

kind regards //S

If you need to show available times, i suggest to separate your response by dates, so if you have one day like datetime(2021, 12, 8) and you want to show times between 11AM and 21PM you can use something like:

from datetime import date, datetime, time

    
date_of_reference = datetime(2021, 12, 8, 0, 0) #your the object of database
initial_time = datetime.combine(date_of_reference.date(), time(11, 0))
final_time = datetime.combine(date_of_reference.date(), time(21,0))

reserved_times = [datetime(2021, 12, 8, 11, 0), datetime(2021, 12, 8, 15, 0)] #reserved_times from database here

hours_between = [datetime.combine(date_of_reference.date(), time(hour + initial_time.hour, 0)) for hour in range(((final_time - initial_time).seconds // 3600) + 1)]
avaliable_hours = [hour for hour in hours_between if hour not in reserved_times]

In your code will be something like

from datetime import datetime, timedelta
from .models import Appointment


# views
def check_available_hours(request):
    day_request = request.GET.get('day','') #day in format yyyy-MM-dd
    date_of_reference = datetime.strptime(day_request, "%Y-%m-%d")
    initial_date_time = date_of_reference
    final_date_time = date_of_reference + timedelta(hours=23)
    appointments_of_day = Appointment.objects.filter(
        start_appointment__gte=initial_date_time,
        start_appointment__lte=final_date_time
    )
    reserved_times = [
        appointment.start_appointment + timedelta(hours=i) for appointment in appointments_of_day for i in range((appointment.end_appointment - appointment.start_appointment).seconds//3600)]
    # same as above but more understandable
    # for appointment in appointments_of_day:
    #     for i in range((appointment.end_appointment - appointment.start_appointment)//3600):
    #         reserved_times.append(appointment.start_appointment + timedelta(hours=i))
    hours_between = [initial_date_time + timedelta(hours=hour) for hour in range(((initial_date_time - final_date_time).seconds // 3600) + 1)]
    avaliable_hours = [hour for hour in hours_between if hour not in reserved_times]
    
    return render(request, "name_template.html", {"hours": avaliable_hours})

If your appointments do not have a duration only in hours, you have to control the minutes of the day instead of the hours as in the example above

Back to Top