Я пытаюсь отфильтровать DateTimeField
по сравнению с датой. Я имею в виду:
MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))
Я получаю пустой список запросов в качестве ответа, потому что (я думаю) я не рассматриваю время, но я хочу "в любое время".
Есть ли простой способ в Django для этого?
У меня есть время в заданном времени, это не 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 с датой слишком сложно" для более подробной информации.
Q(created__gte=datetime.combine(created_value, time.min))
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, поэтому время в базе данных не совпадает.
Вот результаты, которые я получил с функцией 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
содержит, кажется, быстрее.
contains
решение, я получаю сообщение об ошибке: Unable to get repr for <class 'django.db.models.query.QuerySet'>
__contains
. Но если у вас __gte
проблемы, вы должны попробовать пример django docs , использующий __gte
.
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 фильтр запросов для запроса объектов datetime против дат в версии разработки. Таким образом, он скоро будет доступен в 1.9.
Как и в Django 1.9, способ сделать это - __date
в объекте datetime.
Например:
MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))
Предполагая, что active_on является объектом даты, увеличивайте его на 1 день, затем диапазон
next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
Вот интересный метод. Я использовал процедуру 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 не выйдет с решением!
В Django 1.7.6 работает:
MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))
__lte
например.
Hm.. Мое решение работает:
Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))
Здесь есть фантастический блогпост: Сравнение дат и времени в 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(). Таким образом, реализация, эта простая, кажется, будет иметь определенную зависимость от бэкэнда.
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)
См. статью Документация по Django
Его очень похоже на ответ JZ
ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27)