2012-08-06 62 views
4

我的提案模型定義如下:F()的表達和timedelta從F()的表達產生的薩姆

class Proposal(models.Model): 
    scheduled_time = models.DateTimeField() 
    duration = models.IntegerField() # stores minutes as an integer 

    # (extra fields clipped for brevity's sake) 

欲註釋每個提議對象,給它一個「結束」日期時間通過SCHEDULED_TIME計算+持續時間的timedelta表示,例如timedelta(minutes=duration)。但是,F()表達式似乎不適合作爲timedelta()的參數。

>>> from datetime import timedelta 
>>> from django.db.models import F 
>>> from schedule.models import Proposal 
>>> 
>>> proposals = Proposal.objects.all() 
>>> annotated = proposals.annotate(
...  end=F('scheduled_time')+timedelta(minutes=F('duration'))) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
TypeError: unsupported type for timedelta minutes component: F 
>>> 

這種事情可能使用annotate()和F()表達式嗎?

編輯:註釋的目的是能夠過濾/排除計算的結束時間。

+0

貌似'F( '持續時間')'不返回數..( ?) – Qiau 2012-08-06 21:18:50

回答

1

F() -expressions僅適用於django(因爲它們返回特定對象的實例)。除了某些django queryset方法之外,你不能將它們傳遞給timedelta或其他任何東西。

所以你最好的新字段添加到您的模型:

class Proposal(models.Model): 
    scheduled_time = models.DateTimeField() 
    duration = IntegerField() 
    end = models.DateTimeField(default=self.scheduled_time + timedelta(minutes=self.duration)) 
+0

是的,這可能是正確的選擇。我希望有人會用不需要修改模型的解決方案,但我認爲唯一的答案是跳過ORM並使用SQL。 – 2012-08-09 02:59:03

+0

對不起,但這給了 'NameError:name'self'is not defined' 看看我的答案可能的工作解決方案 – malteo 2013-03-15 11:40:15

1

F()不能用這種方式,作爲@Daniil已經指出。

一種可能的解決辦法是增加一個新的字段

end_time = models.DateTimeField() 

和重寫保存方法

def save(self, *args, **kwargs): 
    if not self.end_time: 
     self.end_time = self.scheduled_time + datetime.timedelta(self.duration) 
    super(Proposal, self).save(*args, **kwargs)