简体   繁体   English

在Django中对日期进行交叉检查时,LTE和GTE查询不一致

[英]lte & gte query inconsistent when Crosschecking for dates in Django

I want users to be able to check the calendar for dates already booked so the person won't be able to book a room if it has been booked already. 我希望用户能够查看日历中已预订的日期,以便该人如果已经预订了房间,将无法预订房间。 I used the lte and gte to check for dates but it's very inconsistent. 我使用了lte和gte来检查日期,但是这非常不一致。

See what my DB looks like below. 在下面查看我的数据库的外观。

在此处输入图片说明

The main problem I'm facing, 我面临的主要问题

From June 2 to June 13 have been booked for hotelroom id 1. It's returning available instead of not available. 6月2日至6月13日已预订了ID为1的酒店客房。

>>> start_date='2016-06-02'
>>> end_date='2016-06-13'
>>>    check_for_bookings=HotelCalendar.objects.filter(Q(checkin_booked_date__gte=start_date) | Q(checkout_booked_date__lte=end_date), hotelrooms_id=1)
>>> if check_for_bookings:
...     print 'not available'
... else:
...     print 'available'
...
available
>>>

I selected from June 3 to June 14 and tested it with the below query and it worked. 我从6月3日到6月14日进行选择,并使用以下查询对其进行了测试,并且该方法有效。 It showed that the room is not available. 它表明房间不可用。

>>> start_date='2016-06-03'
>>> end_date='2016-06-14'
>>> check_for_bookings=HotelCalendar.objects.filter(Q(checkin_booked_date__gte=start_date)|Q(checkout_booked_date__lte=end_date), hotelrooms_id=1)
>>> if check_for_bookings:
...     print 'not available'
... else:
...     print 'available'
...
not available

The question is why did the first query failed to return 'not available' when the dates have been booked.? 问题是,预订日期后,为什么第一个查询未能返回“不可用”?

What other query can I run to make it efficient? 我可以运行其他哪些查询来提高效率?

Your conditions have been swapped gte <> lte . 您的条件已交换gte <> lte The second query worked because there is a matching date '2016-06-14' for hotelrooms_id=1 . 第二个查询有效,因为hotelrooms_id=1的匹配日期为'2016-06-14'

But you want to check if start_date and end_date are within range checkin_booked_date to checkout_booked_date : 但是您要检查start_dateend_date是否在checkin_booked_datecheckout_booked_date范围内:

check_for_bookings = HotelCalendar.objects.filter(checkin_booked_date__lte=start_date, 
                                                  checkout_booked_date__gte=end_date,
                                                  hotelrooms_id=1)

Use exists if you only need to check and not fetch the objects: 如果仅需要检查而不需要获取对象,则使用exists

if HotelCalendar.objects.filter(checkin_booked_date__lte=start_date,
                                checkout_booked_date__gte=end_date, 
                                hotelrooms_id=1).exists():

Update: 更新:

From this SO answer , we can tell if start and end dates overlap with the dates of occupancy of a client: 从这个SO答案中 ,我们可以判断开始日期和结束日期是否与客户的入住日期重叠:

from datetime import datetime as dt

hotelcalendar = HotelCalendar.objects.filter(hotelrooms_id=1)

start_date = dt.strptime(start_date, '%Y-%m-%d')
end_date = dt.strptime(end_date, '%Y-%m-%d')

if hotelcalendar.checkin_booked_date <= end_date and hotelcalendar.checkout_booked_date >= start_date:
     print "not available"
else:
     print "available"

Update: 更新:

I tweaked it this way: I changed 'filter' to 'get' because it will return 'AttributeError'. 我以这种方式进行了调整:我将“过滤器”更改为“获取”,因为它将返回“ AttributeError”。 And I used datetime.date() directly. 我直接使用datetime.date() And it worked fine so far! 到目前为止,一切正常!

>>> import datetime
>>> hotelcalendar= HotelCalendar.objects.get(hotelrooms_id=1)
>>> start_date= datetime.date(2016, 06, 14)
>>> end_date= datetime.date(2016, 06, 19)
>>> if hotelcalendar.checkin_booked_date <= end_date and hotelcalendar.checkout_booked_date >= start_date:
...     print 'not available'
... else:
...     print 'available'
...
not available

>>> hotelcalendar= HotelCalendar.objects.get(hotelrooms_id=1)
>>> start_date= datetime.date(2016, 06, 15)
>>> end_date= datetime.date(2016, 06, 19)
>>> if hotelcalendar.checkin_booked_date <= end_date and  hotelcalendar.checkout_booked_date >= start_date:
...     print 'not available'
... else:
...     print 'available'
...
available
>>> hotelcalendar= HotelCalendar.objects.get(hotelrooms_id=3)
>>> start_date= datetime.date(2016, 06, 02)
>>> end_date= datetime.date(2016, 06, 10)
>>> if hotelcalendar.checkin_booked_date <= end_date and hotelcalendar.checkout_booked_date >= start_date:
...     print 'not available'
... else:
...     print 'available'
...
not available
>>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM