Я пытаюсь создать представление создания резервирования, которое позволяет разбить процесс резервирования на 3 этапа для обработки всех запросов к базе данных и отображения соответствующих вариантов выбора в соответствии с связью между моделями (в профиле персонала имеется много-много ключей в Сервисе) 1-й этап - позволяет пользователю выбрать сервис 2-й этап - отображает доступных сотрудников (PersonnelProfile), которые обрабатывают этот сервис 3-й этап - отображает все свободные даты / время на основе расписания сотрудников / существующих резервирований, POST создает резервирование, которое я застрял в 2-й этап, так как моя форма не проверяется. Буду признателен за любой совет, как преодолеть эту проблему или как по-другому относиться к идее. Извините за длинный пост:)
ОБНОВЛЕНИЕ
Моя цель следующая:
1. Пользователь выбирает услугу
2. Бэкэнд проверяет, какие профили персонала предлагают эту услугу, и возвращает из него, чтобы выбрать соответствующего пользователя
3. На основе выбранного бэкэнда проверяет доступность (Расписание) пользователя, его существующие бронирования и форму возврата для выбора даты / часа
4. Резервирование создается после отправки пользователем с выбранным часом и временем
Я пытался сделать это с помощью дополнительных форм, чтобы разбить процесс на этапы, так как понятия не имею (к сожалению, я все еще новичок ie) как справиться с таким поведением с помощью одной формы, и если это возможно или нет. Буду признателен за любые советы / рекомендации о том, как справиться с этим.
Бронирование
class Reservation(models.Model):
user = models.ForeignKey(PersonnelProfile, on_delete=models.PROTECT)
client = models.ForeignKey(ClientProfile, on_delete=models.PROTECT)
service = models.ForeignKey(Service, on_delete=models.PROTECT)
date = models.DateField()
start_time = models.TimeField()
Сервис
class Service(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.IntegerField()
duration = models.IntegerField()
def __str__(self):
return self.name
PersonnelProfile
class PersonnelProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birth_date = models.DateField(default=None, null=True)
address = models.CharField(max_length=200)
services = models.ManyToManyField(Service)
image = models.ImageField(default='profile_pics/default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.first_name} {self.user.last_name}'
Модель расписания
class Schedule(models.Model):
user = models.OneToOneField(PersonnelProfile, on_delete=models.CASCADE)
availability_days = models.ManyToManyField(WorkDay)
start_hour = models.TimeField()
end_hour = models.TimeField()
def __str__(self):
return f'Schedule of {self.user.user.first_name} {self.user.user.last_name}'
Модель WorkDay
class WorkDay(models.Model):
day_choices = [(str(i), calendar.day_name[i]) for i in range(7)]
name = models.CharField(max_length=9, choices=day_choices, default='1', unique=True)
def __str__(self):
return self.get_name_display()
Резервирование CreateView
class ReservationCreate(LoginRequiredMixin, UserPassesTestMixin, ModelFormWidgetMixin, CreateView):
model = Reservation
success_url = '/reservations'
@staticmethod
def get(request):
form = ServiceSelection()
return render(request, 'reservations/reservation_service_selection.html', context={'form': form})
@staticmethod
def post(request):
if 'service_selection' in request.POST:
form = ServiceSelection(request.POST)
if form.is_valid():
service = form.cleaned_data['select_service']
available_personnel = PersonnelProfile.objects.filter(services=service)
personnel_names = [prs.user for prs in available_personnel]
form = PersonSelection(personnel_names)
context = {
'form': form,
'service': service
}
"""
Selected service data should be saved for the 3rd stage
"""
return render(request, 'reservations/reservation_person_selection.html', context)
return HttpResponse('Service incorrect', 404)
if 'person_selection' in request.POST:
form = PersonSelection(request.POST)
if form.is_valid():
"""
Check the schedule and existing reservations
Return last form with available dates and times for service selected in stage 1
and staff member selected in 3rd stage.
3rd stage will create Reservation with all the selected details in all 3 stages
"""
return HttpResponse('Good choice', 200) #response just for tests
return render(request, 'reservations/reservation_person_selection.html', {'form': form})
def test_func(self):
if self.request.user.is_staff:
return True
return False
Формы
class ServiceSelection(forms.ModelForm):
select_service = forms.ModelChoiceField(
queryset=Service.objects.all(),
widget=forms.Select(),
empty_label='Please select a service',
to_field_name='price'
)
class Meta:
model = Service
fields = ('select_service',)
class PersonSelection(forms.ModelForm):
def __init__(self, personnel_names, *args, **kwargs):
super(PersonSelection, self).__init__(*args, **kwargs)
self.fields['user'] = forms.ChoiceField(
choices=tuple([(name, name) for name in personnel_names]),
label='Select a person'
)
class Meta:
model = PersonnelProfile
fields = 'user',
Шаблоны: booking_service_selection
booking_person_selection