简体   繁体   中英

How solve the problem with clean function in django

I'm building a booking website, where customer can book an appointment on a day of his/her choice and the time of appointment is selected from the available slots with the help of drop-down menu. The problem is if a time slot has already been booked by someone it should not be available and an error message should be shown to the customer.

I have written a clean function to perform the check. It gives and error as follows :-

No booking on  2019-06-08
Internal Server Error: /
Traceback (most recent call last):
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/views/generic/base.py", line 97, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/views/generic/edit.py", line 172, in post
    return super().post(request, *args, **kwargs)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/views/generic/edit.py", line 141, in post
    if form.is_valid():
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/forms/forms.py", line 185, in is_valid
    return self.is_bound and not self.errors
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/forms/forms.py", line 180, in errors
    self.full_clean()
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/forms/forms.py", line 383, in full_clean
    self._post_clean()
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/forms/models.py", line 403, in _post_clean
    self.instance.full_clean(exclude=exclude, validate_unique=False)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/db/models/base.py", line 1181, in full_clean
    self.clean_fields(exclude=exclude)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/db/models/base.py", line 1223, in clean_fields
    setattr(self, f.attname, f.clean(raw_value, self))
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 629, in clean
    value = self.to_python(value)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 2187, in to_python
    parsed = parse_time(value)
  File "/home/gireesh/PycharmProjects/astrobookinenv/lib/python3.6/site-packages/django/utils/dateparse.py", line 89, in parse_time
    match = time_re.match(value)
TypeError: expected string or bytes-like object

The Code for the clean function :-

    def clean_booking_time(self):
        booked_time = self.cleaned_data['booking_time']
        booked_date = self.cleaned_data['booking_date']
        # count = Booking.objects.filter(booking_date=booked_date).filter(booking_time=booked_time).count()
        count_date = Booking.objects.filter(booking_date=booked_date).count()
        if count_date == 0:
            print("No booking on ",booked_date)
            return self.cleaned_data
        else:
            count_time = Booking.objects.filter(booking_date=booked_date).filter(booking_time=booked_time).count()
            if count_time != 0:
                error_message = "%s is not available !" % booked_time
                raise ValidationError(error_message)
            else:
                return self.cleaned_data

If I book an appointment by removing the clean it'll save successfully and then if I add the code back and try to book on the same time the code works fine and throws the error. It only seem not to work when the date has no booking. Problem might be with the ORM I have written.

You're returning the cleaned_data dict in a field-specific clean method. You are supposed to return just the value for that field.

However it seems that this should actually be the overall clean() method, since it references multiple fields. That method is meant to return the whole dict.

Just rename the method to clean .

You should return the booking_time data for the clean_booking_time function:

def clean_booking_time(self):
    booked_time = self.cleaned_data['booking_time']
    booked_date = self.cleaned_data['booking_date']
    booking_exists = Booking.objects.filter(
        booking_date=booked_date,
        booking_time=booked_time
    ).exists()
    if booking_exists:
        error_message = "%s is not available !" % booked_time
        raise ValidationError(error_message)
    return 

It furthermore is a bit odd that you clean a specific field here, since your cleaning constrains the relation between two fields.

That being said, you might want to consider a DateTimeField [Django-doc] that contains both the time and the date.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM