Я пишу программу бронирования с использованием администратора Django.Программа предупредит пользователя (через Django сообщения ), когда общее количество ночей для всех изменений номера больше, чем общее количество ночей для бронирования.Поэтому, если бронь рассчитана на 7 ночей, и пользователь вводит гостя в комнату «А» на 4 ночи и в комнату «Б» на 4 ночи (всего 8 ночей), пользователь увидит предупреждение.Причина предупреждения, а не простой ошибки формы, заключается в том, что в группе может быть несколько комнат за ночь, что может привести к тому, что вышеперечисленное произойдет.
Код работает (ниже приведены соответствующие фрагменты).
warn_if_rc_nights_gt_reservation_nights()
, который содержит логику для предупреждения пользователя, работает с экземпляром формы (когда форма только отображается) или с необработанными переменными request.POST (когда форма сохраняется / отправляется)чтобы подсчитать общее количество ночей для смены номеров и бронирования.
Я в порядке с использованием экземпляра формы для подсчета общего количества ночей, но у меня проблема с необработанными переменными POST, так как это большая ошибка-prone (переменные POST еще не clean()
) и не-Django-подобный.Я бы предпочел использовать встроенный метод класса или функцию для достижения этой цели.
Я пытался сделать это:
- Внутри form.clean ()метод .Это работает только при сохранении формы, поэтому пользователь не видит предупреждение при простой навигации по странице.
- Использование различных сигналов Django. Не удалось найти сигнал, который имелвсе объекты, которые мне понадобились для выполнения действия и которые будут срабатывать при любых обстоятельствах.
reservations.models
class Room(models.Model):
room_number = models.CharField(max_length=16)
class Reservation(models.Model):
# Guest is in guest.models
guest = models.ForeignKey(Guest, on_delete=models.CASCADE)
check_in_date = models.DateField()
check_out_date = models.DateField()
class RoomChange(models.Model):
reservation = models.ForeignKey(Reservation on_delete=models.CASCADE)
room = models.ForeignKey(Room on_delete=models.CASCADE)
day_in = models.DateField()
day_out = models.DateField()
reservations.admin
@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
# Uses a form factory to capture the request object.
self.form = _reservation_form_factory(request)
return super().get_form(request, obj, **kwargs)
@admin.register(Room)
class RoomAdmin(admin.ModelAdmin):
pass
@admin.register(RoomChange)
class RoomChangeAdmin(admin.ModelAdmin):
pass
reservations.forms
def _reservation_form_factory(request):
class ReservationAdminForm(forms.ModelForm):
class Meta:
exclude = []
model = Reservation
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Warn the user if total room change nights > reservation total nights
warn_if_rc_nights_gt_reservation_nights(request.POST, self.instance)
return ReservationAdminForm
Поэтому в конечном итоге я прошу более простой, менее подверженный ошибкам способ выполнения этой задачи.