Django中datetime.datetime与datetime.date无法比较问题求助
解决datetime与date无法比较的问题
问题根源
你表单里的check_in、check_out是DateField,最终得到的是datetime.date类型数据;但数据库中Booking模型的对应字段应该是DateTimeField(存储了日期+时间),两种类型直接比较就会抛出can't compare datetime.datetime to datetime.date错误。
方案一:修改表单字段为DateTimeField
既然你的输入格式包含时间(%Y-%m-%dT%H:%M),直接把表单字段改成DateTimeField更匹配:
check_in = forms.DateTimeField(required=True, input_formats=["%Y-%m-%dT%H:%M", ]) check_out = forms.DateTimeField(required=True, input_formats=["%Y-%m-%dT%H:%M", ])
这样表单清洗后的数据就是datetime.datetime类型,和数据库字段类型一致,直接比较就不会出错。
方案二:转换类型后再比较
如果不想改表单字段,就在check_availability函数里统一类型后再比较:
方式1:将数据库的datetime转为date
修改check_availability函数的比较逻辑:
import datetime def check_availability(room, check_in, check_out): avail_list = [] booking_list = Booking.objects.filter(room=room) for booking in booking_list: # 把数据库的datetime转成date再比较 if booking.check_in.date() > check_out or booking.check_out.date() < check_in: avail_list.append(True) else: avail_list.append(False) return all(avail_list)
方式2:将传入的date转为datetime
如果需要保留时间维度的比较,可以把表单传入的date转成当天的起始/结束datetime:
import datetime def check_availability(room, check_in, check_out): avail_list = [] # 将date转为datetime:check_in设为当天0点,check_out设为当天23:59:59 check_in_dt = datetime.datetime.combine(check_in, datetime.time.min) check_out_dt = datetime.datetime.combine(check_out, datetime.time.max) booking_list = Booking.objects.filter(room=room) for booking in booking_list: if booking.check_in > check_out_dt or booking.check_out < check_in_dt: avail_list.append(True) else: avail_list.append(False) return all(avail_list)
额外优化建议
你的check_availability可以简化写法,直接用数据库查询判断会更高效:
def check_availability(room, check_in, check_out): # 这里根据你选的方案调整类型,比如用方案1的话就用date() overlapping = Booking.objects.filter( room=room, check_in__date__lte=check_out, check_out__date__gte=check_in ).exists() return not overlapping
直接通过数据库查询判断是否有重叠预订,比循环Python列表效率高很多,尤其是预订数据量大的时候。
内容的提问来源于stack exchange,提问作者mr.pepper
相关产品推荐
相关产品推荐

