如何在Django中过滤DateTimeField的日期?

时间:2009-08-23 03:52:08

标签: python django datetime filter django-queryset

我正在尝试根据日期过滤DateTimeField。我的意思是:

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

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

Django有这么简单的方法吗?

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

17 个答案:

答案 0 :(得分:108)

此类查找在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 Comparing a DateTimeField to a date is too hard”了解更多详情。

答案 1 :(得分:90)

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

//在评论后编辑

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

不起作用,因为它创建了一个时间值设置为0的日期时间对象,因此数据库中的时间不匹配。

答案 2 :(得分:77)

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

包含似乎更快。

答案 3 :(得分:37)

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

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

答案 4 :(得分:36)

现在Django有__date个查询集过滤器来查询日期时间对象与开发版本中的日期。因此,它很快将在1.9中提供。

答案 5 :(得分:25)

这会产生与使用__year,__ month和__day相同的结果,似乎对我有用:

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

答案 6 :(得分:23)

从Django 1.9开始,执行此操作的方法是在日期时间对象上使用__date

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

答案 7 :(得分:7)

假设active_on是日期对象,将其递增1天,然后执行范围

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

答案 8 :(得分:2)

这是一个有趣的技术 - 我利用MySQL上的Django实现的startswith过程来实现仅通过日期查找日期时间的结果。基本上,当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提出解决方案!

答案 9 :(得分:1)

嗯..我的解决方案正在运行:

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

答案 10 :(得分:0)

您可以在某些日期范围之间进行过滤

2016-01-01 00:00:00 <--> 2016-04-01 23:59:59.99999

User.objects.filter(date_joined__gte=datetime.combine(datetime.strptime('2016- 
01-01', '%Y-%d-%m'), datetime.min.time()), 
date_joined__lte=datetime.combine(datetime.strptime('2016-04-01', '%Y-%d-%m'), 
datetime.max.time())).count()

2016-01-01 00:00:00 <--> 2016-01-14 00:00:00

User.objects.filter(date_joined__gte='2016-01-01', date_joined__lte='2016-1-14').count()

答案 11 :(得分:0)

你可以这样做

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

或者如果您想在 2 个日期之间进行过滤

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

答案 12 :(得分:0)

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

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

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

答案 13 :(得分:0)

在Django 1.7.6作品中:

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

答案 14 :(得分:0)

这里有一个很棒的博客文章:Comparing Dates and Datetimes in the Django ORM

为Django&gt; 1.7发布的最佳解决方案,&lt; 1.9是注册转换:

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()

然后你可以在你的过滤器中使用它:

Foo.objects.filter(created_on__date=date)

修改

此解决方案肯定是后端依赖的。来自文章:

  

当然,这种实现依赖于具有DATE()函数的SQL的特殊风格。 MySQL确实如此。 SQLite也是如此。另一方面,我没有亲自使用PostgreSQL,但是一些谷歌搜索让我相信它没有DATE()函数。所以这个简单的实现似乎必然会依赖于后端。

答案 15 :(得分:0)

Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)

答案 16 :(得分:0)

请参阅文章Django Documentation

它非常类似于JZ答案

ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27)