简体   繁体   中英

Django Filter by date and status

My first question here, I've been looking around but couldn't find a solution.

I am building a reservation system, my models are

class Room(models.Model):
    number = models.IntegerField()
    beds = models.IntegerField()
    capacity = models.IntegerField()
    category = models.ForeignKey(
        RoomCategory, on_delete=models.CASCADE, blank=True, null=True)

class Booking(models.Model):
    room = models.ForeignKey(Room, on_delete=models.CASCADE, blank=True, null=True)
    check_in = models.DateField()
    check_out = models.DateField()
    status = models.IntegerField(blank=True, null=True)

 if request.method == 'POST':
        no_disponible = "No hay habitaciones disponibles, selecciona otras fechas"

        if form.is_valid():

            room_list = Room.objects.filter(category=1).exclude(booking__check_in__lt=form.cleaned_data['check_out'],
                                                                booking__check_out__gt=form.cleaned_data['check_in'], booking__status__gt=0)

I am changing status when the customer confirms so I want to check if dates are available when status is not 1 (I change status to 1 once the payment is approved. However booking__status__gt=0 doesn't seem to work here

Based on your query, you want to exclude rooms with:

  1. Bookings with check ins that are less than the requested check out.
  2. Bookings with check outs that are greater than the requested check in.
  3. Bookings with status greater than 0.

Your current query is:

Room.objects.filter(category=1).exclude(
    booking__check_in__lt=form.cleaned_data['check_out'],
    booking__check_out__gt=form.cleaned_data['check_in'], 
    booking__status__gt=0,
)

This will remove all rooms that have status greater than 0, as well as rooms with invalid checkin/checkout dates, even though some of those rooms with invalid checkin/checkout dates have status as 0. This is because of how exclude works when it spans multi-valued relationships like this.

To fix this, change your query to get all the bookings with the exclusions you want by using Booking , and then compare it against the reverse relationship:

Room.objects.filter(category=1).exclude(
    booking__in=Booking.objects.filter(
        check_in__lt=form.cleaned_data['check_out'],
        check_out__gt=form.cleaned_data['check_in'],
        status__gt=0,
    )
)

Have a read here to understand the behaviour of exclude in this case more.

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