Тема: Бронювання без перетину часу із попередніми бронюваннями
Мови, технології: Python, Django, sqlite3, Django REST framework
Інтегроване середовище розробки: PyCharm
Добрий день!
Розробляю сайт для замовлення (бронювання) спортивної риболовлі на рибному господарстві. Майже так само, як при бронюванні проживання в готелі. Тільки замість кімнати – рибальський пірс.
Я хочу написати умову збереження даних в базі бронювання, де заброньований час не буде перетинатися з раніше заброньованим. З урахуванням обраного пірсу.
Наприклад:
Рибалка Іван забронював "Пірс 1" з 6:00 до 13:00. А рибалка Петро хотів забронювати в той же день той самий «Пірс 1» з 11:00 до 21:00. Але код (можливо валідатор) не дозволить Петру це зробити, тому що з 11:00 до 13:00 «Пірс 1» ще зайнятий Іваном. Петро може вибрати інший час або вибрати інший «Пірс 2», «Пірс 3». Сподіваюся, ви мене зрозуміли.
Отже, models.py наступний:
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
from django.db import models
from django.core.exceptions import ValidationError
class BookingPier(models.Model):
pier = models.ForeignKey('Pier', on_delete=models.PROTECT, null=True, verbose_name='Пірс')
PIER_STATUS_CHOICES = [
("<span class='bk'>бронь</span>", "бронь"),
("<span class='fr'>вільний</span>", "вільний"),
]
pier_status = models.CharField(max_length=40, choices=PIER_STATUS_CHOICES, default="бронь",
verbose_name='Стан пірсу')
time_booking_start = models.DateTimeField(auto_now_add=False, auto_now=False, blank=True, null=True,
verbose_name='Прибуття',
validators=[validate_booking_time])
time_booking_finish = models.DateTimeField(auto_now_add=False, auto_now=False, blank=True, null=True,
verbose_name='Відбуття',
validators=[validate_booking_time])
wish = models.CharField(max_length=255, verbose_name='Побажання')
time_create = models.DateTimeField(auto_now_add=True, verbose_name='Час створення')
time_update = models.DateTimeField(auto_now=True, verbose_name='Час публікації')
is_published = models.BooleanField(default=True, verbose_name='Публікація')
user = models.ForeignKey(User, verbose_name='Користувач', on_delete=models.CASCADE)
class Pier(models.Model):
name = models.CharField(max_length=100, db_index=True)
def __str__(self):
return self.name
Я намагався написати валідатор, приведу приклад одного із них
def validate_booking_time(self):
# отримуємо всі бронювання для вибраного пірсу
bookings = BookingPier.objects.filter(pier=self.pier)
# перевіряємо, чи є час, що перетинається
for booking in bookings:
if (
self.time_booking_start >= booking.time_booking_start and self.time_booking_start < booking.time_booking_finish) or (
self.time_booking_finish > booking.time_booking_start and self.time_booking_finish <= booking.time_booking_finish):
raise ValidationError(_('Вибраний час перетинаєтсья з іншим бронюванням для цього пірсу'))
Але видається наступна помилка:
AttributeError: 'datetime.datetime' object has no attribute 'pier'
[09/Jan/2023 22:04:22] "POST /api/v1/bookingpier/ HTTP/1.1" 500 127571
Змінював 'pier' на 'pier_id' (як в базі даних). Не допомагає.
Вперше роблю таке і не знаю, чи валідатори взагалі призначені для даного випадку. Потрібна допомога більш досвідчених програмістів.
Слава Україні !
Слава Нації !