如何过滤Django中的DateTimeField的date?

我正在尝试过滤DateTimeField比较date。 我的意思是:

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

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

Django中有这样一个简单的方法吗?

我有时间在设定的date时间,它不是00:00

这样的查找在django.views.generic.date_based中实现,如下所示:

 {'date_time_field__range': (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max))} 

因为它非常详细,所以有计划使用__date运算符来改进语法。 检查“ #9596比较DateTimeField到date太难 ”更多详细信息。

 YourModel.objects.filter(datetime_published__year='2008', datetime_published__month='03', datetime_published__day='27') 

//在评论之后编辑

 YourModel.objects.filter(datetime_published=datetime(2008, 03, 27)) 

doest不起作用,因为它创build了一个datetime对象,其时间值设置为0,所以数据库中的时间不匹配。

下面是我用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 

包含似乎更快。

 Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28)) 

以上是我用过的。 它不仅工作,而且还有一些固有的逻辑支持。

这产生了与使用__year,__month和__day相同的结果,似乎为我工作:

 YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22)) 

现在,Django具有__date querysetfilter,可以根据开发版本中的date查询datetime对象。 因此,它很快就会在1.9上市。

从Django 1.9开始,做这件事的方法是在datetime对象上使用__date

例如: MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))

假设active_on是一个date对象,增加1天然后做范围

 next_day = active_on + datetime.timedelta(1) queryset = queryset.filter(date_created__range=(active_on, next_day) ) 

这是一个有趣的技术 – 我利用了Django在MySQL上实现的startswith过程,以实现只通过date查找date时间的结果。 基本上,当Django在数据库中进行查找时,必须对DATETIME MySQL存储对象进行string转换,因此可以对此进行过滤,从而省去date的时间戳部分 – 这样%LIKE%只匹配date对象,你会得到给定date的每个时间戳。

 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将匹配date的所有内容,而不pipe时间戳。 包括如下的值:

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

希望这可以帮助大家,直到Django出来一个解决scheme!

嗯..我的解决scheme正在工作:

 Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28)) 

在Django 1.7.6中的作品:

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

请参阅文章Django文档

它与JZ的答案非常相似

 ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27) 
 Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30) 

这里有一个很棒的博客post: 比较Django ORM中的date和date时间

Django> 1.7,<1.9的最佳解决scheme是注册一个转换:

 from django.db import models class MySQLDatetimeDate(models.Transform): """ This implements a custom SQL lookup when using `__date` with datetimes. To enable filtering on datetimes that fall on a given date, import this transform and register it with the DateTimeField. """ lookup_name = 'date' def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) return 'DATE({})'.format(lhs), params @property def output_field(self): return models.DateField() 

那么你可以在你的filter中使用它:

 Foo.objects.filter(created_on__date=date) 

编辑

这个解决scheme肯定是后端的依赖。 从文章:

当然,这个实现依赖于你具有DATE()函数的特定的SQL风格。 MySQL的确如此。 SQLite也是如此。 另一方面,我没有亲自使用PostgreSQL,但是一些Google使我相信它没有DATE()函数。 所以这个简单的实现看起来就像后端依赖。