我有以下型号:
class House(models.Model):
Name = models.CharField(max_length=200, unique=True)
Reference = models.CharField(max_length=50, unique=True)
class Booking(models.Model):
House = models.ForeignKey(House, related_name='booking')
InitialDate = models.DateField()
FinalDate= models.DateField()
现在,我想执行查询以过滤范围日期的所有可用房屋(例如:2013-07-21至2013-07-30),因此它应排除所有预订开始和结束的房屋在这两个日期之间。 我可以使用原始SQL执行此查询,但不能使用django语法执行此查询。
有人可以帮忙吗?
非常感谢!
答案 0 :(得分:4)
当使用Django ORM时,使用的一种做法是,你应该始终以你想要结束的关系开始,在你的情况下House
。
我认为这将是你实现目标的方式:
unbooked_houses = House.objects.exclude(
booking__InitialDate__gte=start_date, booking_FinalDate__lte=end_date)
通过这种方式,您最终会得到QuerySet
,无需担心列表推导等等。
此外,Python PEP-8文档规定您应遵循以下变量和属性的命名约定:
而不是InitialDate
,最好是initial_date
。
答案 1 :(得分:3)
我采取了更自由的案例。
class House(models.Model):
name = models.CharField(max_length=200, unique=True)
reference = models.CharField(max_length=50, unique=True)
class Booking(models.Model):
house = models.ForeignKey(House, related_name='booking')
initial_date = models.DateField()
final_date= models.DateField()
import datetime
start_date = datetime.datetime(2013, 07, 21)
end_date = datetime.datetime(2013, 07, 30)
# so simply intersect
booked = set(values['house_id'] for values in Booking.objects.objects.filter(
initial_date__lte=end_date, final_date__gte=start_date).values('house_id'))
House.objects.exclude(id__in=booked)
thanx to richsilv的设定理念,合乎逻辑,但我通过阅读他的答案来了解它。它只是通过使用不同的房屋来简化sql语句。
答案 2 :(得分:0)
假设您所谈论的时间段介于startdate
和enddate
之间,那么这会有效吗?
booked = set([x.House.Reference for x in \
Booking.objects.filter(InitialDate__lte=enddate).filter(FinalDate__gte=startdate)])
available = House.objects.exclude(Reference__in=booked)
答案 3 :(得分:0)
由于Django创建的反向关系,可以直接过滤:
bookedHouses = House.objects.filter(booking__InitialDate__lte=enddate)\
.filter(booking__FinalDate__gte=startdate)