如何在Django中使用清理功能解决问题

时间:2019-06-07 13:20:36

标签: python django database postgresql orm

我正在建立一个预订网站,客户可以在该天选择自己想预约的日期,并借助下拉菜单从可用的时段中选择约会时间。问题是如果某人已经预订了一个时间段,则该时间段将不可用,并且应该向客户显示错误消息。

我写了一个干净的函数来执行检查。它给出和错误如下:-

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

清除功能的代码:-

    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

如果我通过取消清理来预订约会,它将成功保存,然后如果我重新添加代码并尝试同时预订,则代码可以正常工作并抛出错误。只有在没有预定日期的情况下,它似乎才失效。我写的ORM可能有问题。

2 个答案:

答案 0 :(得分:2)

您将以特定于字段的clean方法返回cleaned_data dict。您应该只返回该字段的值。

但是,似乎它实际上应该是整体clean()方法,因为它引用了多个字段。该方法 旨在返回整个字典。

只需将方法重命名为clean

答案 1 :(得分:1)

您应该为booking_time函数返回clean_booking_time数据:

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 booked_time

此外,您在此处清理特定于 的字段有点奇怪,因为清理会限制两个字段之间的关系。

话虽如此,您可能要考虑同时包含时间和日期的DateTimeField [Django-doc]