Как удалить уже выбранную опцию из списка опций, чтобы избежать двойного бронирования
Я уже 2 дня ломаю голову над этим вопросом в надежде на внезапное озарение и ни к чему не пришел. Я полностью запутался в своей логике и все попытки привели к тому, что я сломал свой код. Я пытаюсь сделать так, чтобы в определенную дату, если пользователь уже выбрал тайм-слот с выбранным парикмахером, этот тайм-слот был удален из списка тайм-слотов, так что он не может быть выбран снова другим пользователем
Из models.py
from django.db import models
import datetime
from django.core.validators import MinValueValidator
from django.contrib.auth.models import User
SERVICES = (
('Gents Cut', 'Gents Cut'),
('Kids Cut', 'Kids Cut'),
('Cut and Shave', 'Cut and Shave'),
('Shave Only', 'Shave Only'),
)
TIME_SLOTS = (
('9.00 - 10.00', '9.00 - 10.00'),
('10.00 - 11.00', '10.00 - 11.00'),
('11.00 - 12.00', '11.00 - 12.00'),
('12.00 - 13.00', '12.00 - 13.00'),
('13.00 - 14.00', '13.00 - 14.00'),
('14.00 - 15.00', '14.00 - 15.00'),
('15.00 - 16.00', '15.00 - 16.00'),
('16.00 - 17.00', '16.00 - 17.00'),
('17.00 - 18.00', '17.00 - 18.00'),
)
BARBER_NAME = (
('Nathan', 'Nathan'),
('Chris', 'Chris'),
('Ben', 'Ben'),
('Dan', 'Dan'),
)
class Booking(models.Model):
date = models.DateField(validators=[MinValueValidator(datetime.date.today)])
time = models.CharField(max_length=50, null=True, choices=TIME_SLOTS)
barber = models.CharField(max_length=50, null=True, choices=BARBER_NAME)
service = models.CharField(max_length=50, null=True, choices=SERVICES)
customer = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return f"{self.customer} has booked {self.service} on {self.date} at {self.time} with {self.barber}"
из файла views.py
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.views import generic, View
from django.contrib import messages
from django.http import HttpResponseRedirect
from .models import Booking
from .forms import BookingForm
@login_required()
def make_booking(request):
if request.method == "POST":
form = BookingForm(request.POST)
if form.is_valid():
booking_form = form.save(commit=False)
booking_form.customer = request.user
booking_form.save()
messages.success(request, ('Your booking is awaiting confirmation'))
return HttpResponseRedirect('/bookings')
else:
form = BookingForm()
return render(request, 'bookings.html', {'form': form})
из файла forms.py
from .models import Booking
import datetime
from django import forms
class DatePicker(forms.DateInput):
input_type = 'date'
class BookingForm(forms.ModelForm):
class Meta:
model = Booking
fields = ('date', 'time', 'barber', 'service',)
widgets = {
'date': DatePicker(),
}
Так или иначе, вам понадобится другое представление, которое будет принимать выбранную дату и возвращать доступные временные интервалы. Если вы хотите сделать это с помощью AJAX, то ваше представление может выглядеть примерно так:
import json
from datetime import datetime
def get_time_slots(request):
# get the date in python format, sent via ajax request
date = datetime.strptime(request.GET.get('date'), '%Y-%m-%d')
# get all times from bookings on the provided date
booked_slots = Booking.objects.filter(date=date).values_list('time', flat=True)
available_slots = []
for slots in TIME_SLOTS:
if slots[0] not in booked_slots:
available_slots.append(slots)
times_as_json = json.dumps(available_slots)
return JsonResponse(times_as_json)
Лучшим способом, по моему мнению, было бы создание новых моделей для тайм-слотов, услуг и парикмахеров. Во-первых, вы не храните информацию в жестком коде и можете динамически изменять ее в БД. Во-вторых, вы можете создать очень простой запрос для получения доступных тайм-слотов на день, парикмахера, услуги и т.д. Вы также можете установить общую доступность, связав определенных парикмахеров с определенными временными интервалами, в зависимости от часов их работы.