Как я могу отфильтровать дату DateTimeField в Django? - PullRequest
154 голосов
/ 23 августа 2009

Я пытаюсь отфильтровать DateTimeField по сравнению с датой. Я имею в виду:

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

Я получаю пустой список наборов запросов в качестве ответа, потому что (я думаю) я не считаю время, но хочу "в любое время".

Есть ли в Джанго простой способ сделать это?

У меня установлено время в дате, оно не 00:00.

Ответы [ 14 ]

109 голосов
/ 29 декабря 2009

Такие поиски реализованы в 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 с датой слишком сложно " для получения более подробной информации.

91 голосов
/ 23 августа 2009
YourModel.objects.filter(datetime_published__year='2008', 
                         datetime_published__month='03', 
                         datetime_published__day='27')

// редактировать после комментариев

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

не работает, потому что он создает объект datetime со значениями времени, установленными в 0, поэтому время в базе данных не совпадает.

78 голосов
/ 24 июня 2012

Вот результаты, которые я получил с помощью функции timeit ipython:

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

содержит , кажется, быстрее.

38 голосов
/ 23 февраля 2012
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))

выше, что я использовал. Он не только работает, но и имеет некоторую внутреннюю логическую поддержку.

36 голосов
/ 28 августа 2015

Теперь у Django есть фильтр запросов __ date для запроса объектов даты и времени к датам в версии разработки. Таким образом, он будет доступен в 1.9 в ближайшее время.

25 голосов
/ 15 февраля 2010

Это дает те же результаты, что и при использовании __year, __month и __day, и, похоже, работает для меня:

YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
23 голосов
/ 07 апреля 2016

Начиная с Django 1.9, способ сделать это - использовать __date для объекта datetime.

Например: MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))

8 голосов
/ 27 июня 2013

если предположить, что active_on является объектом даты, увеличить его на 1 день, затем сделать диапазон

next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
2 голосов
/ 20 августа 2012

Вот интересный метод - я использовал процедуру стартов с Django, реализованную в MySQL, чтобы добиться результата только поиска даты и времени только по дате.По сути, когда 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 не найдет решение!

1 голос
/ 27 мая 2010

Хм .. Мое решение работает:

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