1

我有以下模型:

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 语法。

有人可以帮忙吗?

非常感谢!

4

4 回答 4

4

When using the Django ORM one of the practices used is that you should always start with the relationship you want to end up with, in your case House.

I argue that this would be your way of going about it then:

unbooked_houses = House.objects.exclude(
    booking__InitialDate__gte=start_date, booking_FinalDate__lte=end_date)

This way you'll end up with a QuerySet and need not bother with list comprehensions and whatnot.

Furthermore, Python PEP-8 document dictates that you should follow the following naming convention for variables and properties:

Instead of InitialDate it should preferably be initial_date.

于 2013-07-23T10:27:41.840 回答
3

我自由地使用了一个更 Pythonic 的案例。

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)

感谢richsilv的设定想法,合乎逻辑,但我通过阅读他的回答想到了这一点。它只是通过仅使用不同的房屋来减少 sql 语句。

于 2013-07-23T10:11:26.287 回答
0

由于 Django 创建的反向关系,可以直接过滤:

bookedHouses = House.objects.filter(booking__InitialDate__lte=enddate)\ .filter(booking__FinalDate__gte=startdate)

于 2013-07-23T10:10:06.523 回答
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)
于 2013-07-23T10:06:20.040 回答