Администратор Django отправляет сообщение на основе встроенного набора форм - PullRequest
0 голосов
/ 23 ноября 2018

Я пишу программу бронирования с использованием администратора 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

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

...