Проблемы фильтрации поля django datetime по месяцам и дням

Может кто-нибудь объяснить мне, почему следующие фильтры не работают на уровне месяца и дня? Фильтрация по годам работает, но не две другие.

>>> clicks.count()
36
>>> date = clicks[0].created
>>> date.month
2
>>> date.year
2014
>>> date.day
1
>>> clicks.filter(created__month=2)
[]
>>> clicks.filter(created__month=02)
[]
>>> clicks.filter(created__month='02')
[]
>>> clicks.filter(created__month='2')
[]
>>> clicks.filter(created__month=date.month)
[]
>>> clicks.filter(created__day=date.day)
[]

Быстрое обновление, чтобы продемонстрировать, что я получаю такое же поведение перед созданием и обработкой набора запросов:

>>> clicks = PreviewClick.objects.filter(created__month = 2)
>>> clicks.count()
0
>>> clicks = PreviewClick.objects.filter(created__month = 02)
>>> clicks.count()
0
>>> clicks = PreviewClick.objects.filter(created__month = '02')
>>> clicks.count()
0
>>> clicks = PreviewClick.objects.filter(created__month = '2')
>>> clicks.count()
0

Здесь больше пищи для размышлений:

>>> clicks = PreviewClick.objects.all()
>>> counter = 0
>>> for click in clicks:
...      if click.created.month == 2:
...           counter += 1
... 
>>> counter
35

Ответ 1

Я видел то же поведение, что и вы.

Если вы проверите документацию для 1.6 и набора запросов на месяц. Они добавили следующий абзац:

"Когда USE_TZ имеет значение True, поля datetime преобразуются в текущий часовой пояс перед фильтрацией. Для этого требуются определения часовых поясов в базе данных.

Если вы измените следующую строку в своих настройках на False, тогда вы должны начать получать обратно данные, которые вы ожидаете.

USE_TZ = False

Ответ 2

@Simon Wilder отлично отвечает за то, почему он не работает, вот как вы можете его решить, не отключая поддержку TZ в django

Документ Django предоставляет инструкцию для установки определения временной зоны в базу данных:

SQLite: install pytz - преобразования фактически выполняются на Python.

PostgreSQL: нет требований (см. Временные зоны).

Oracle: нет требований (см. Выбор файла временной зоны).

MySQL: установите pytz и загрузите таблицы часовых поясов с помощью mysql_tzinfo_to_sql.

В моем случае: mysql и Mac Os, следующая команда разрешает проблему:

sudo mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql -u root mysql

Ответ 3

Ваш синтаксис неверен. Это должно быть:

Clicks.objects.filter(created__month=2)

(вы остановились у менеджера объектов)

Ответ 4

Чтобы обновить ответ здесь, так как я столкнулся с вышеупомянутой проблемой, но ни одно из решений не работало. Большинство новых установок mysql предварительно устанавливаются с помощью tz-info, поэтому команда mysql_tzinfo_to_sql не поможет. И установка TZ_INFO в False на самом деле не является решением, поскольку многие из них нуждаются в времени и времени, которые известны во временной зоне.

Итак, что сработало для меня, было создать объект datetime, поддерживающий tz, и проверить на это. Допустим, вы хотите фильтровать записи на сегодня, вы бы сделали что-то вроде:

from datetime import datetime
import pytz

today = datetime.now().replace(tzinfo=pytz.UTC).date()   # tz aware datetime object
todays_records = myModel.objects.filter(created__year=today.year, created__month=today.month,created__day=today.day)

Надеюсь, что это поможет.