201

我正在尝试过滤DateTimeField与日期的比较。我是说:

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

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

Django中有一个简单的方法可以做到这一点吗?

我在日期时间设置了时间,它不是00:00

4

19 回答 19

122

这样的查找实现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 与日期进行比较太难”以获取更多详细信息。

于 2009-12-29T10:23:03.197 回答
113
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 的日期时间对象,因此数据库中的时间不匹配。

于 2009-08-23T04:02:35.997 回答
111

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

包含似乎更快。

于 2012-06-24T02:31:03.900 回答
63

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

于 2015-08-28T12:44:37.627 回答
46
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))

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

于 2012-02-23T14:11:08.147 回答
44

从 Django 1.9 开始,执行此操作的方法是使用__datedatetime 对象。

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

于 2016-04-06T21:47:07.537 回答
27

这会产生与使用 __year、__month 和 __day 相同的结果,并且似乎对我有用:

YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
于 2010-02-14T21:05:12.603 回答
8

假设 active_on 是一个日期对象,将它增加 1 天然后做范围

next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
于 2013-06-27T19:14:04.760 回答
7

你可以这样做

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))
)
于 2021-05-10T12:52:08.543 回答
4

这里有一篇很棒的博客文章:比较 Django ORM 中的日期和日期时间

为 Django>1.7,<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() 函数。因此,如此简单的实现似乎必然在某种程度上依赖于后端。

于 2015-10-19T18:12:09.660 回答
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 提出解决方案!

于 2012-08-20T17:54:36.113 回答
1

您可以按日期过滤,因为日期格式与您的 django 日期格式相同。默认格式为 ISO YYYY-MM-DD

target_date = "2009-08-22"
qs = MyObject.objects.filter(datetime_attr__date=target_date)
于 2021-11-19T14:24:00.470 回答
0
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)
于 2009-09-13T15:15:52.550 回答
0

请参阅文章Django 文档

ur_data_model.objects.filter(ur_date_field__gte=datetime(2009, 8, 22), ur_date_field__lt=datetime(2009, 8, 23))
于 2009-08-23T04:11:15.807 回答
0

嗯..我的解决方案正在工作:

Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))
于 2010-05-27T03:38:27.357 回答
0
person = Profile.objects.get(id=1)

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

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

于 2021-01-15T03:51:57.307 回答
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()
于 2021-05-24T19:02:20.453 回答
0

在 Django 1.7.6 中工作:

MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))
于 2016-04-19T09:35:26.213 回答
-1

就像你有一个日期时间字段一样简单,你可以使用 datetime.date.today()

context['now'] = Mymodel.objects.filter(date_time_field=datetime.date.today())
于 2021-08-12T14:37:24.553 回答