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