2010-11-04 43 views
2

有沒有辦法使用update()方法增加過濾對象的年份?如何使用update()在Django的datetimefield中增加年份?

我使用:

python 2.6.5 
django 1.2.1 final 
mysql Ver 14.14 Distrib 5.1.41 

我知道這是可以做到這樣的事情:

today = datetime.datetime.today() 
for event in Event.objects.filter(end_date__lt=today).iterator(): 
    event.start_date = festival.start_date + datetime.timedelta(365) 
    event.end_date = festival.end_date + datetime.timedelta(365) 
    event.save() 

然而,在某些情況下,我寧願使用update()方法。

# This does not work.. 

Event.objects.all().update(
      start_date=F('start_date') + datetime.timedelta(365), 
      end_date=F('end_date') + datetime.timedelta(365) 
      ) 

上面的例子,我得到:

Warning: Truncated incorrect DOUBLE value: '365 0:0:0' 

它試圖使SQL查詢:

UPDATE `events_event` SET `start_date` = `events_event`.`start_date` + 365 days, 0:00:00, `end_date` = `events_event`.`end_date` + 365 days, 0:00:00 

我發現了MySQL指南中的東西,但是這是生SQL!

SELECT DATE_ADD('2008-12-15', INTERVAL 1 YEAR); 

任何想法?

+1

似乎是一個開放的車票與補丁:http://code.djangoproject.com/ticket/10154 – OmerGertel 2010-11-04 06:08:46

回答

0

快速醜陋:

>>> a.created.timetuple() 
time.struct_time(tm_year=2000, tm_mon=11, tm_mday=2, tm_hour=2, tm_min=35, tm_se 
c=14, tm_wday=3, tm_yday=307, tm_isdst=-1) 
>>> time = list(a.created.timetuple()) 
>>> time[0] = time[0] + 1 
>>> time 
[2001, 11, 2, 2, 35, 14, 3, 307, -1] 
>>> 
0
from dateutil.relativedelta import relativedelta 

yourdate = datetime.datetime(2010, 11, 4, 10, 14, 54, 518749) 
yourdate += relativedelta(years=+1) 

Relativedelta需要許多時間參數,從秒到年...

+0

這個問題不計算額外的一年。使用django的更新的好處是,原始日期不會從數據庫中取出。你的建議與@louis在他的問題頂部提出的建議類似 - 從數據庫中獲取日期,修改並保存回去。這需要兩個查詢而不是一個查詢。 – OmerGertel 2010-11-04 08:44:12

+0

抱歉...一種不可能的解決方案可能是使用F來重新分配值,但我認爲這不可能用於日期字段......以下是F的文檔:http://docs.djangoproject.com/ en/dev/topics/db/queries /#updates-multiple-objects-at-once – FallenAngel 2010-11-04 09:16:38

0

你見過這樣的:Increating a datime field with queryset.update?我還記得成功使用帶有MySQL後端的timedelta的queryset .update()。

+0

感謝您的建議,但我仍然收到警告:截斷不正確的DOUBLE值:'365 0:0:0' – Louis 2010-11-04 11:18:30

1

一個潛在的原因「警告:數據被截斷列X」例外是被添加到的DateField爲timedelta使用非全日值 - 這是蟒蛇精,但寫入時失敗到MySQL數據庫。如果您有DateTimeField,它也可以工作,因爲持久字段的精度與timedelta的精度相匹配。

即:

>>> from django.db.models import F 
>>> from datetime import timedelta 
>>> from myapp.models import MyModel 
>>> [field for field in MyModel._meta.fields if field.name == 'valid_until'][0] 
<django.db.models.fields.DateField object at 0x3d72fd0> 
>>> [field for field in MyModel._meta.fields if field.name == 'timestamp'][0] 
<django.db.models.fields.DateTimeField object at 0x43756d0> 
>>> MyModel.objects.filter(pk=1).update(valid_until=F('valid_until') + timedelta(days=3)) 
1L 
>>> MyModel.objects.filter(pk=1).update(valid_until=F('valid_until') + timedelta(days=3.5)) 
Traceback (most recent call last): 
... 
Warning: Data truncated for column 'valid_until' at row 1 
>>> MyModel.objects.filter(pk=1).update(timestamp=F('timestamp') + timedelta(days=3.5)) 
1L