0

I'm working on a project for a hotel , i have to prevent from select wrong dates for example

check_in = 27-6-2021 2:30PM 
check_out = 30-6-2021 2:30PM 

i want to prevent from selecting any date into that two dates for example check_in=28-6-2021 2:30PM check_out=2-7-2021 2:30PM and so on .. this is my Booking model

class Booking(models.Model):
    admin = models.ForeignKey(User,on_delete=models.CASCADE)
    room_no = models.ForeignKey(Room,on_delete=models.CASCADE,blank=True,related_name='rooms')
    takes_by = models.ManyToManyField(Vistor)
    check_in = models.DateTimeField(default=datetime.now)
    check_out = models.DateTimeField()

#my form

class BookingForm(forms.ModelForm):
    takes_by = forms.ModelMultipleChoiceField(queryset=Vistor.objects.all())
    check_in = forms.DateTimeField(required=True,input_formats=['%Y-%m-%dT%H:%M','%Y-%m-%dT%H:M%Z'],widget=forms.DateTimeInput(attrs={'type':'datetime-local'}))
    check_out = forms.DateTimeField(required=True,input_formats=['%Y-%m-%dT%H:%M','%Y-%m-%dT%H:M%Z'],widget=forms.DateTimeInput(attrs={'type':'datetime-local'}))
    class Meta:
        model = Booking
        fields = ['takes_by','check_in','check_out']

my views.py

@login_required
def add_booking(request,room_no):
   room_number = get_object_or_404(Room,room_no=room_no)
   if request.method == 'POST':
        form = BookingForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.room_no = room_number
            obj.admin = request.user
            obj.save()  
            messages.success(request,f'room number {room_number} added')
   form = BookingForm()

   return render(request,'booking/add_booking.html',{'form':form,'room_number':room_number})

what should i do to prevent from takes a room in an existing date twice ? thank you so much

artiest
  • 554
  • 5
  • 20
  • 1
    mysql saves its dates in yyyy-mm--dd hh:mm::ss so try to use that – nbk Jun 27 '21 at 12:34
  • i'll change it , but i have to filter the date to prevent from taking the same room at the same existing time – artiest Jun 27 '21 at 12:35
  • 1
    there is a canonocal thread about filtering dates https://stackoverflow.com/questions/1317714/how-can-i-filter-a-date-of-a-datetimefield-in-django – nbk Jun 27 '21 at 13:08

2 Answers2

1

You can check if the check in check out for the particular room already exists or not like this.

from django.db.models import Q

def add_booking(request,room_no):
   room_number = get_object_or_404(Room,room_no=room_no)
   if request.method == 'POST':
      form = BookingForm(request.POST)
      if form.is_valid():
          check_in = form.cleaned_data.get('check_in')
          check_out = form.cleaned_data.get('check_out')
          if room_number.rooms.filter(Q(check_in_gte=check_in)|Q(check_out_lte=check_out)).exists():
              return HttpResponse('invalid check in out date')
          obj = form.save(commit=False)
          obj.room_no = room_number
          obj.admin = request.user
          obj.save()  
arjun
  • 7,230
  • 4
  • 12
  • 29
  • thank you for your replay , but it doesnt work for all cases – artiest Jun 27 '21 at 13:38
  • what does the *all cases* mean can you give more detail ? – arjun Jun 27 '21 at 13:41
  • i've add this `check_in=27-6-2021 4:30 p.m , check_out=1-7-2021 4:30 p.m` , but still it allows me to add these two dates for the other booking `check_in=28-6-2021 4:30 p.m , check_out=2-7-2021 4:30 p.m` for the same room – artiest Jun 27 '21 at 13:46
  • it had to prevent from creating another booking at that time – artiest Jun 27 '21 at 13:47
  • it always shows `invalid check in out date` even if the dates doesn't taken – artiest Jun 28 '21 at 07:43
0

You can use a clear function in your form:

        def clean_check_in(self):
    check_in = self.cleaned_data['check_in']
    excluded_date_start = #the begining date of exclusion
    excluded_date_end =  # the end date of exclusion

    if check_in > excluded_date_start and check_in < excluded_date_end :
        raise ValidationError("not possible to book")

    return check_in
Gwenael
  • 66
  • 3
  • thank you , but we have to compare both two fields `check_in,check_out` and how to get the `excluded_date_start , excluded_date_end ` , can explain it more please – artiest Jun 28 '21 at 07:29
  • 1
    you can do the same for your check_out. the excluded dates are the ones you retrieve from previous bookings. You may need to create a function to check what are the nearest previous check out (that correspond to the excluded_date_start) and the nearest next check_in (that correspond to the excluded_date_end) – Gwenael Jun 28 '21 at 07:43
  • ill try and let know to the result – artiest Jun 28 '21 at 07:53