2

I am trying to create a reservation form that creates an object for model Reservation when the form is posted. I am using a custom datepicker widget to pick the ate, but I am also using ModelForms.

The issue is that, if I do not have 'date' listed in the meta fields list in the forms.py, then the form doesn't look for the date field form input on post. But if I include 'date' inside the meta fields of the forms.py Modelform, then it errors and says "date field can not be left blank" even though it is not blank...

forms.py

class ReservationForm(forms.ModelForm):

    date = forms.DateField(
        widget=DatePickerInput(format='%m/%d/%Y')
        )
    def clean_date(self):
        data = self.cleaned_data['date']

        # Check if a date is not in the past.
        if data < datetime.date.today():
            raise ValidationError(_('Invalid date - reservation in past'), code='invalid')
            messages.danger(request, "Reservation Created")
            print('ERROR')


            # Remember to always return the cleaned date.
            return data

    class Meta:
        model = Reservation
        fields = ('reservation_time', 'people', 'name', 'email', 'phone') # REMOVED 'date'

views.py

def reservationFormView(request):
    #reservation = create(Reservation)
        # If this is a POST request then process the Form data
    if request.method == 'POST':
        # Create a form instance and populate it with data from the request (binding):
        form = ReservationForm(request.POST)

        # Check if the form is valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required

            reservation = form.save(commit=False)
            reservation.ReservationEmail = form.cleaned_data['email']
            reservation.ReservationName = form.cleaned_data['name']
            reservation.ReservationPeople = form.cleaned_data['people']
            reservation.ReservationTime = form.cleaned_data['reservation_time']
            reservation.date = form.cleaned_data['date']
            print( reservation.date)
            #reservation.created_time = timezone.now()
            reservation.save()

                # redirect to a new URL:
            return HttpResponseRedirect('/reservation-confirmation/')

        # If this is a GET (or any other method) create the default form.
    else:
        form = ReservationForm()

    return render(request, 'home/reservation_form.html', {'form': form, })

models.py

class Reservation(BaseModel):
    class Meta:
        verbose_name_plural = "Reservations"

    TIME_CHOICES = (
...
    )
    SEATING_CHOICES = (
...
    )
    date = models.DateField(null=True)
    name = models.CharField(max_length=35, null=True)
    phone = PhoneNumberField(null=True)   #USE THIS https://github.com/stefanfoulis/django-phonenumber-field
    email = models.EmailField(null=True)
    people = models.PositiveSmallIntegerField(choices=SEATING_CHOICES, default=None, db_index=True)
    reservation_time = models.PositiveSmallIntegerField(choices=TIME_CHOICES, default=None, db_index=True)

    def __str__(self):
        return '(%s) %s %s' % (self.date, self.name, self.phone )
4
  • You wrote return data in the body of the if part, not at the end of the method. Commented May 16, 2019 at 18:26
  • Thank you for the input, you are correct, that solved the issue.
    – Dominic M.
    Commented May 16, 2019 at 18:27
  • 1
    no the indentation is too much. If you look at the documentation you refer to, the return ... is indented under the def clean_date, not the if. Commented May 16, 2019 at 18:28
  • I edited the reply, thank you!
    – Dominic M.
    Commented May 16, 2019 at 18:29

1 Answer 1

2

Your clean_date method does not return a value in case the if condition is False. You should return the cleaned data in case it is correct, like:

def clean_date(self):
    data = self.cleaned_data['date']

    # Check if a date is not in the past.
    if data < datetime.date.today():
        raise ValidationError(_('Invalid date - reservation in past'), code='invalid')
        messages.danger(request, "Reservation Created")

    # not indented under the if
    return data

Otherwise, this function will return None in case the data is valid, and raise a ValidationError in case the data is invalid.

Not the answer you're looking for? Browse other questions tagged or ask your own question.