0

I am developing a Reservation System in Django. I have a booking model, and in views the logic to make new booking and also to edit bookings. The logic in creating new bookings works perfectly but I am having problems when editing it. Basically, what I need to achieve is:

  • If I edit my reservation but I don't change any data, I want the form to be saved
  • If I edit my reservation and I change some data, I want the form to be saved ONLY if it doesn't overlap with any other reservation. I post some code:

models.py

class Booking(models.Model):
    aircraft = models.ForeignKey(Aircraft, on_delete=models.CASCADE)
    student = models.ForeignKey(
        Student, on_delete=models.CASCADE, blank=True, null=True)
    instructor = models.ForeignKey(
        Instructor, on_delete=models.CASCADE, blank=True, null=True)
    renter = models.ForeignKey(
        Renter, on_delete=models.CASCADE, blank=True, null=True)
    booking_date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()
    uid = models.CharField(max_length=200, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

The uid field I created is a sort of logic to have a kind of Unique ID of the reservation in order to check if anything changed when I edit the booking.

views.py

if request.method == "POST":
        aircraft = request.POST.get('aircraft')
        student = request.POST.get('student')
        instructor = request.POST.get('instructor')
        renter = request.POST.get('renter')
        date = request.POST.get('date')
        start_time = request.POST.get('start_time')
        end_time = request.POST.get('end_time')
        try:
            booking.aircraft_id = aircraft
            booking.student_id = student
            booking.instructor_id = instructor
            booking.renter_id = renter
            booking.booking_date = date
            booking.start_time = start_time
            booking.end_time = end_time
            booking.uid = uid_for_booking(aircraft, date, start_time, end_time)

            case_1 = Booking.objects.filter(
                aircraft=aircraft, booking_date=date, start_time__lt=start_time, end_time__gt=start_time).exists()
            case_2 = Booking.objects.filter(
                aircraft=aircraft, booking_date=date, start_time__lte=end_time, end_time__gte=end_time).exists()
            case_3 = Booking.objects.filter(
                aircraft=aircraft, booking_date=date, start_time__gte=start_time, end_time__lte=end_time).exists()
            if (case_1 or case_2 or case_3) and (booking_obj.uid != booking.uid):
                messages.error(request, 'Aircraft Already Booked')
                return HttpResponseRedirect(reverse('booking:edit_booking', kwargs={'pk': pk}))
            elif booking.uid == booking_obj.uid:
                booking.save()
            else:
                booking.save()
            messages.success(request, "Booking Successfully Edited")
            return HttpResponseRedirect(reverse('booking:booking_index', kwargs={'data': date}))
        except:
            messages.error(request, "Failed to Edit Booking")
            return HttpResponseRedirect(reverse('booking:booking_index', kwargs={'pk': pk}))

uid_for_booking method:

def uid_for_booking(a, b, c, d):
    aircraft = str(a)
    date = str(b)
    start_time = str(c)
    end_time = str(d)
    uid = aircraft + date + start_time + end_time
    return uid

I googled to find if there is any possible solution but so far I wasn't lucky. I think my problem is actually in the logic in the check in the views, but I couldn't figure out how to solve it.

Giorgio Scarso
  • 386
  • 1
  • 2
  • 11
  • 1
    You don't need an if..else case for saving data… Each time you save, you confirm that *this reservation doesn't overlap with any other reservation.* This can be done each time regardless of whether data changed. If no data changed, the validation should pass, just as it did last time. And figuring out whether it overlaps should be a fairly simple query about counting reservations within the timeframe, excluding this specific reservation you're editing… – deceze Jul 14 '22 at 10:30
  • Actually, my problem is that I HAVE to check the case_1, case_2 or case_3, otherwise it may overlap another existing reservation. Shall I check, if the id of the case_1, case_2 or case_3 are equal to the id of my reservation in case? – Giorgio Scarso Jul 14 '22 at 10:43
  • Does this help? https://stackoverflow.com/a/143568/476 – deceze Jul 14 '22 at 10:47
  • Yeah, thank you very much. I understood and worked it out. – Giorgio Scarso Jul 14 '22 at 11:07

0 Answers0