我试图过滤一个DateTimeField与日期比较。我的意思是:

MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))

我得到一个空的查询集列表作为答案,因为(我认为)我没有考虑时间,但我想要“任何时间”。

Django中有简单的方法来做这个吗?

我在datetime中设置了时间,不是00:00。


当前回答

这里有一个有趣的技术——我利用Django在MySQL上实现的startswith过程来实现仅通过日期查找datetime的结果。基本上,当Django在数据库中查找时,它必须为DATETIME MySQL存储对象做一个字符串转换,所以你可以过滤它,忽略日期的时间戳部分——这样%LIKE%只匹配日期对象,你会得到给定日期的每个时间戳。

datetime_filter = datetime(2009, 8, 22) 
MyObject.objects.filter(datetime_attr__startswith=datetime_filter.date())

这将执行以下查询:

SELECT (values) FROM myapp_my_object \ 
WHERE myapp_my_object.datetime_attr LIKE BINARY 2009-08-22%

在这种情况下,LIKE BINARY将匹配日期的所有内容,而不管时间戳是什么。包括如下值:

+---------------------+
| datetime_attr       |
+---------------------+
| 2009-08-22 11:05:08 |
+---------------------+

希望这能帮助到每个人,直到Django拿出解决方案!

其他回答

现在Django在开发版本中有__date queryset过滤器来根据日期查询datetime对象。因此,它将很快在1.9中可用。

在Django 1.7.6中工作:

MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))

下面是我使用ipython的timeit函数得到的结果:

from datetime import date
today = date.today()

timeit[Model.objects.filter(date_created__year=today.year, date_created__month=today.month, date_created__day=today.day)]
1000 loops, best of 3: 652 us per loop

timeit[Model.objects.filter(date_created__gte=today)]
1000 loops, best of 3: 631 us per loop

timeit[Model.objects.filter(date_created__startswith=today)]
1000 loops, best of 3: 541 us per loop

timeit[Model.objects.filter(date_created__contains=today)]
1000 loops, best of 3: 536 us per loop

Contains似乎更快。

person = Profile.objects.get(id=1)

tasks = Task.objects.filter(assigned_to=person, time_stamp__year=person.time_stamp.utcnow().year)

我所有的模型都有time_stamp,所以我使用person对象来获取当前年份

你可以根据日期进行过滤,因为日期格式与django的日期格式相同。默认格式为“ISO YYYY-MM-DD”

target_date = "2009-08-22"
qs = MyObject.objects.filter(datetime_attr__date=target_date)