Как я могу отфильтровать дату DateTimeField в Django?

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

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

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

Есть ли простой способ в Django для этого?

У меня есть время в заданном времени, это не 00:00.

Ответ 1

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

Ответ 2

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 не работает, потому что он создает объект datetime со значениями времени, установленными в 0, поэтому время в базе данных не совпадает.

Ответ 3

Вот результаты, которые я получил с функцией 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

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

Ответ 4

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

это то, что я использовал. Он не только работает, но и обладает некоторой логической поддержкой.

Ответ 5

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

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

Ответ 6

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

Ответ 7

Как и в Django 1.9, способ сделать это - __date в объекте datetime.

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

Ответ 8

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

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

Ответ 9

Вот интересный метод. Я использовал процедуру startswith, реализованную с 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 не выйдет с решением!

Ответ 10

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

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

Ответ 11

В Django 1.7.6 работает:

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

Ответ 12

См. статью Документация по Django

Его очень похоже на ответ JZ

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

Ответ 13

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

Ответ 14

Здесь есть фантастический блогпост: Сравнение дат и времени в ORM Django

Лучшее решение для 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)

ИЗМЕНИТЬ

Это решение, безусловно, зависит от конца. Из статьи:

Конечно, эта реализация зависит от вашего особого вкуса SQL, имеющего функцию DATE(). MySQL делает. Так делает SQLite. С другой стороны, я не работал с PostgreSQL лично, но некоторый googling заставляет меня думать, что у него нет функции DATE(). Таким образом, реализация, эта простая, кажется, будет иметь определенную зависимость от бэкэнда.