Показывать временные интервалы после щелчка на календаре дат

У меня есть два поля в Django Model, поле Date и поле Time,

class Appointment(models.Model):
    section = models.ForeignKey(
        'Section',
        verbose_name=_('Section'),
        related_name='section_appointments',
        null=True,
        blank=True,
        on_delete=models.CASCADE
    )
    doctor = models.ForeignKey(
        'Doctor',
        verbose_name=_('Doctor'),
        related_name='doctor_appointments',
        null=True,
        blank=True,
        on_delete=models.CASCADE
    )
    name = models.CharField(
        verbose_name=_('Full Name'),
        max_length=255
    )
    email = models.EmailField(
        verbose_name=_('Email Address'),
        max_length=255,
        blank=True,
        validators=[EmailValidator(message=_("Enter a valid email address."))]
    )
    date = models.DateField(
        verbose_name=_('Appointment Date')
    )
    time = models.TimeField(
        verbose_name=_('Appointment Time')
    )
    created_at = models.DateTimeField(
        auto_now_add=True
    )

данная модель используется как мастер форм, состоящий из 3 форм (выбор раздела и врача, затем выбор даты и времени, затем заполнение необходимой информации о пациенте для планирования приема)

когда я перехожу к шагу -2- дата и время, я хочу показать календарь с предопределенными датами (из профиля врача), а также определенные временные интервалы для каждой даты, как показать временные интервалы после выбора даты из календаря, есть ли какой-нибудь JS плагин для того же UI? или если я хочу создать его с нуля, как это сделать?

Прилагаю скриншот для описанного мною случая time_slots_on_date_click

Любое предложение от перспективного фронтенда было бы очень признательно.

Для достижения функциональности, когда выбор даты показывает определенные временные интервалы для встреч в Django, вы можете объединить Django для логики бэкенда и JavaScript для интерактивности фронтенда. Вот пошаговое руководство по достижению этой цели:

Шаг 1: Определение моделей

Во-первых, убедитесь, что ваши модели настроены на хранение свободных временных интервалов для врачей. Возможно, вам понадобится дополнительная модель для хранения информации о доступности.

from django.db import models
from django.utils.translation import gettext_lazy as _
from django.core.validators import EmailValidator

class Section(models.Model):
    name = models.CharField(max_length=100)

class Doctor(models.Model):
    name = models.CharField(max_length=100)
    section = models.ForeignKey(Section, on_delete=models.CASCADE)

class DoctorAvailability(models.Model):
    doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
    date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()

class Appointment(models.Model):
    section = models.ForeignKey(
        Section,
        verbose_name=_('Section'),
        related_name='section_appointments',
        null=True,
        blank=True,
        on_delete=models.CASCADE
    )
    doctor = models.ForeignKey(
        Doctor,
        verbose_name=_('Doctor'),
        related_name='doctor_appointments',
        null=True,
        blank=True,
        on_delete=models.CASCADE
    )
    name = models.CharField(
        verbose_name=_('Full Name'),
        max_length=255
    )
    email = models.EmailField(
        verbose_name=_('Email Address'),
        max_length=255,
        blank=True,
        validators=[EmailValidator(message=_("Enter a valid email address."))]
    )
    date = models.DateField(
        verbose_name=_('Appointment Date')
    )
    time = models.TimeField(
        verbose_name=_('Appointment Time')
    )
    created_at = models.DateTimeField(
        auto_now_add=True
    )

Шаг 2: Создание представлений

Создайте представление, которое будет обрабатывать выборку доступных временных интервалов для определенной даты и врача.

from django.shortcuts import render
from django.http import JsonResponse
from .models import DoctorAvailability

def get_time_slots(request):
    doctor_id = request.GET.get('doctor_id')
    date = request.GET.get('date')
    
    if doctor_id and date:
        availabilities = DoctorAvailability.objects.filter(doctor_id=doctor_id, date=date)
        time_slots = []
        for availability in availabilities:
            start = availability.start_time
            end = availability.end_time
            # Assuming 30 minutes slots
            while start < end:
                time_slots.append(start.strftime("%H:%M"))
                start = (datetime.combine(date.today(), start) + timedelta(minutes=30)).time()
        return JsonResponse(time_slots, safe=False)
    return JsonResponse([], safe=False)

Шаг 3: Настройка URL

Добавьте конфигурацию URL для нового представления.

from django.urls import path
from . import views

urlpatterns = [
    # other urls
    path('get-time-slots/', views.get_time_slots, name='get_time_slots'),
]

Шаг 4: Обновление шаблона и JavaScript

Обновите свой шаблон, включив в него функцию выбора даты и используя JavaScript для получения и отображения временных интервалов при выборе даты.

<!DOCTYPE html>
<html>
<head>
    <title>Appointment Booking</title>
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <form id="appointment-form">
        <label for="doctor">Doctor:</label>
        <select id="doctor" name="doctor">
            {% for doctor in doctors %}
            <option value="{{ doctor.id }}">{{ doctor.name }}</option>
            {% endfor %}
        </select>
        <label for="date">Date:</label>
        <input type="text" id="datepicker" name="date">
        <label for="time">Time:</label>
        <select id="time-slots" name="time">
            <!-- Options will be populated here -->
        </select>
    </form>

    <script type="text/javascript">
        $(function() {
            $("#datepicker").datepicker({
                dateFormat: 'yy-mm-dd',
                onSelect: function(dateText) {
                    var doctorId = $("#doctor").val();
                    $.ajax({
                        url: "{% url 'get_time_slots' %}",
                        data: {
                            'doctor_id': doctorId,
                            'date': dateText
                        },
                        success: function(data) {
                            var timeSlots = $("#time-slots");
                            timeSlots.empty();
                            if (data.length > 0) {
                                data.forEach(function(time) {
                                    timeSlots.append(new Option(time, time));
                                });
                            } else {
                                timeSlots.append(new Option("No available time slots", ""));
                            }
                        }
                    });
                }
            });
        });
    </script>
</body>
</html>

Шаг 5: Улучшение пользовательского интерфейса

Для создания более продвинутого пользовательского интерфейса с выбором даты и времени можно использовать такие библиотеки, как FullCalendar. Вот пример использования FullCalendar:

  • Включите CSS и JS FullCalendar в ваш шаблон.

<link href='https://fullcalendar.io/releases/fullcalendar/3.9.0/fullcalendar.min.css' rel='stylesheet'>
<script src='https://fullcalendar.io/releases/fullcalendar/3.9.0/lib/moment.min.js'></script>
<script src='https://fullcalendar.io/releases/fullcalendar/3.9.0/fullcalendar.min.js'></script>
  • Инициализируйте FullCalendar в своем шаблоне.

$(document).ready(function() {
        $('#calendar').fullCalendar({
            selectable: true,
            selectHelper: true,
            events: function(start, end, timezone, callback) {
                // Fetch and display available dates from your backend
            },
            select: function(start, end) {
                var doctorId = $("#doctor").val();
                var date = start.format('YYYY-MM-DD');
                $.ajax({
                    url: "{% url 'get_time_slots' %}",
                    data: {
                        'doctor_id': doctorId,
                        'date': date
                    },
                    success: function(data) {
                        var timeSlots = $("#time-slots");
                        timeSlots.empty();
                        if (data.length > 0) {
                            data.forEach(function(time) {
                                timeSlots.append(new Option(time, time));
                            });
                        } else {
                            timeSlots.append(new Option("No available time slots", ""));
                        }
                    }
                });
            }
        });
    });

Выполнив эти шаги, вы получите работающую систему записи на прием, в которой при выборе даты отображаются свободные временные интервалы для выбранного врача.

Вернуться на верх