2012-06-28 28 views
12

我努力從邏輯上表示Django過濾器中的以下內容。我有一個「事件」模型和定位模型,它可以表示爲:今天發生的Django過濾器事件

class Location(models.Model): 
    name = models.CharField(max_length=255) 

class Event(models.Model): 
    start_date = models.DateTimeField() 
    end_date = models.DateTimeField() 
    location = models.ForeignKeyField(Location) 

    objects = EventManager() 

對於一個給定的位置,我想選擇今天發生的所有事件。我已經通過在eventmanager進行了「bookings_today」的方法嘗試了各種策略,但正確的過濾器語法躲開我:

class EventManager(models.Manager): 
    def bookings_today(self, location_id): 
     bookings = self.filter(location=location_id, start=?, end=?) 

日期(),因爲這將清零的時間出現故障時,白天的時間是關鍵該應用程序,同樣適用於日期的最小值和最大值,並將它們用作擋書。此外,還有多個可能的有效配置:

start_date < today, end_date during today 
start_date during today, end_date during today 
start_date during today, end_date after today 

我需要編寫一整套不同的選擇或者是有一個更簡單巧妙的方法?

+1

看看範圍內運營商之間的SQL也看到這個答案由@danielroseman:http://stackoverflow.com/questions/3963201/如何在兩個日期之間選擇與django –

回答

19

你需要兩個不同的閾值datetime - today_starttoday_end

from datetime import datetime, timedelta, time 

today = datetime.now().date() 
tomorrow = today + timedelta(1) 
today_start = datetime.combine(today, time()) 
today_end = datetime.combine(tomorrow, time()) 

什麼今天發生的事情以前一定today_end開始today_start後結束,所以:

class EventManager(models.Manager): 
    def bookings_today(self, location_id): 
     # Construction of today_end/today_start as above, omitted for brevity 
     return self.filter(location=location_id, start__lte=today_end, end__gte=today_start) 

(P.S.有一個DateTimeField(不是DateField)呼籲foo_date是不快誤導性 - 只考慮startend ...)

+0

啊哈 - 輝煌!謝謝。 – jvc26

+1

'datetime.now()'請 – lajarre

1

這個怎麼樣:pub_date__gte=datetime(2005, 1, 1)?使用鏈接方法,使用_gte__lte限制一天內的開始和結束。可能是self.filter(start__gte=datetime(2005, 1, 1)).filter(end__lte=datetime(2005, 1, 1))lte代表小於或等於,gte代表大於或等於。

我在django doc找到它。

5

您需要使用範圍有這樣的:

class EventManager(models.Manager): 
    def bookings_today(self, location_id): 
     from datetime import datetime 
     now = datetime.now() 
     bookings = self.filter(location=location_id, start__lte=now, end__gte=now) 
     return bookings 
+0

如果事件的開始和結束都在今天之內會發生什麼?這不會挑起來 - 這可能是一個* headdesk *時刻,但會把end__gte =今天和start__lte =今天解決這個問題? – jvc26

+0

是的,你說得對。 end__gte = today並且start__lte = today應該被使用。 –

+0

對,這實際上並不起作用,因爲開始日期可能會在今天開始之前或之後下降,而date.today()在選擇期間看起來並不與日期時間對象相等。 – jvc26

0

我認爲排除是你的朋友在這裏!

today = datetime.date.today() 
tomorrow = today + datetime.timedelta(days = 1) 
self.filter(location = location_id).exclude(end_date__lt = today).exclude(start_date__gte = tomorrow) 
1

無我看到的答案是時區察覺。

你爲什麼不只是這樣做,而不是:

from django.utils import timezone 

class EventManager(models.Manager): 
    def bookings_today(self, location_id): 
     bookings = self.filter(location=location_id, start__gte=timezone.now().replace(hour=0, minute=0, second=0), end__lte=timezone.now().replace(hour=23, minute=59, second=59))