Как проверить поле на основе его начального значения в forms.py? - PullRequest
1 голос
/ 07 июля 2019

У меня есть собственный метод self.clean в forms.py, который содержит проверку того, перекрываются ли значения даты POSTed с существующими записями.В случае, когда пользователь редактирует свою запись, но не меняет даты, эта проверка останавливает обновление записи.Как я могу изменить валидацию с помощью оператора If или иным образом зависеть от того, изменил ли пользователь поля start_date или end_date?

Я пробовал смотреть на такие вещи, как self.get_initial () и self.has_changed (), которыекажется, применимы только в функции просмотра?Я предпочел бы проверить в файле forms.py.

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

forms.py:

class EditBookingForm(ModelForm):
    class Meta:
        model = Bookings
        #user not included as that is handled in views
        fields = ['start_date', 'end_date', 'type', 'approved', 'members', 'guests']
...
    def clean(self):
        form_data = self.cleaned_data    

        #check if dates overlap by more than one day (ie. can start/end on the same day)
        overlap_in = Bookings.objects.filter(start_date__lt=form_data['start_date'], end_date__gt=form_data['end_date']).count()
        overlap_st = Bookings.objects.filter(start_date__lt=form_data['start_date'], end_date__gt=form_data['start_date']).count()
        overlap_end = Bookings.objects.filter(start_date__lt=form_data['end_date'], end_date__gt=form_data['end_date']).count()
        overlap_same = Bookings.objects.filter(start_date=form_data['start_date'], end_date=form_data['end_date']).count()       
        overlap_over = Bookings.objects.filter(end_date__gt=form_data['start_date'], start_date__lt=form_data['end_date']).count()

        overlap = overlap_end + overlap_in + overlap_same + overlap_st + overlap_over

        if overlap > 0:
            self._errors["start_date"] = ["Your dates overlap with an existing booking"]
            del form_data["start_date"]
            return form_data


views.py:


    booking = get_object_or_404(Bookings, pk=booking_id)

    if request.method == "POST":
        form = EditBookingForm(request.POST)

        if form.is_valid():
            #some code

    #if not POST request  
    else:
        form = EditBookingForm(instance=booking)

context = {
        'form': form,
    }

    return render(request, 'bookings/edit_booking_page.html', context)

1 Ответ

0 голосов
/ 07 июля 2019

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

bookings = Bookings.objects.all()

if self.instance.pk:
    bookings = bookings.exclude(pk=self.instance.pk)

overlap_in = bookings.filter(start_date__lt=form_data['start_date'], end_date__gt=form_data['end_date']).count()
# etc

Ваши 5 наборов запросов могут быть упрощены до не более 3, если вы подтвердите, что end_date больше, чем start_date. Вероятно, можно уменьшить их до 1 ...

    # So long as end_date is greater than start_date then this should be covered by overlap_st
    # overlap_in = Bookings.objects.filter(start_date__lt=form_data['start_date'], end_date__gt=form_data['end_date']).count()
    overlap_st = Bookings.objects.filter(start_date__lt=form_data['start_date'], end_date__gt=form_data['start_date']).count()
    # So long as end_date is greater than start_date then this should be covered by overlap_over 
    # overlap_end = Bookings.objects.filter(start_date__lt=form_data['end_date'], end_date__gt=form_data['end_date']).count()
    overlap_same = Bookings.objects.filter(start_date=form_data['start_date'], end_date=form_data['end_date']).count()       
    overlap_over = Bookings.objects.filter(end_date__gt=form_data['start_date'], start_date__lt=form_data['end_date']).count()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...