2013-07-16 67 views
1

好吧,我的問題是有點如下:Django的查詢:「日期時間+增量」作爲表達

假設我有一個模型,這是一個簡單的例子:

class Period(models.Model): 
    name = CharField(... field specs here ...) 
    start_date = DateTimeField(... field specs here ...) 
    duration = ... don't know what field should i use but this has to hold a delta ... 

我會喜歡檢索對象,其中(start_date + duration)<現在在Django查詢(我知道我可以,在Python中,測試像my_date_time + a_time_delta < datetime.now(),但事實並非如此...我需要它作爲查詢的一部分)。

我該如何得到它?

回答

2

我認爲你快速的答案是從你減去現在的日期時間與從模型日期時間這樣的補充:

.filter(start_date__lte=datetime.now()-timedelta(days=duration)) 
+0

謝謝你,幫助我。這真的是noob問題,我做了xDDD。 但是...如果我需要比較另一個領域呢? 例如 .filter(start_date__lte = F('another_datetime_field') - timedelta(...))是否允許? **編輯**:我很抱歉,但我需要從模型中獲得持續時間。這意味着:duration和start_date都是特定於實例的。 –

+0

我不認爲有一種方法可以通過ORM在單個查詢中執行此操作。我認爲你的選擇是要麼接受使用兩個查詢,要麼使用'extra'子句將適合數據庫的日期算術放回到約束中。 –

+0

是的...我會嘗試「.extra(where = ...)」我昨天想到 –

2

作爲過濾器依賴於相同型號的兩個屬性,你就需要使用F() expressionduration部分,同時將其與某種timedelta結合使用。目前在Django ORM中不支持這一點。

不過,您可以使用extra()調用。這種方法的缺點是它不是數據庫不可知的。這是PostgreSQL:

Period.objects.extra(
    where=["start_date + duration * INTERVAL '1 day' < %s"], 
    params=[datetime.now()] 
) 

假設你的持續時間是天。如果沒有,則相應調整。

+0

是否有一種等效的方式來處理不同的數據庫? –

1

您可能希望避免使用在你的Django ORM查詢extra,這樣你就可以申請下一個解決方法:

1)添加計算字段和更新每個模型的save(你應該根據自己的邏輯調整保存邏輯)

class Period(models.Model): 
    name = CharField() 
    start_date = DateTimeField() 
    duration = IntegerField(help_text='hours') 
    end_date = DateTimeField() 

def save(self, *args, **kwargs): 
    self.end_date = self.start_date + datetime.timedelta(days=self.duration) 
    super(Period, self).save(*args, **kwargs) 

2),然後使用計算字段在查詢:

finished = Period.objects.filter(end_date__lt=datetime.datetime.now())