Django ORM выполняет запрос с неправильным временем? - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь получить данные на основе поля DateTime ! Я написал следующий скрипт для того же:

import datetime as dt

from dasboard.models import Visionsystem 
from django.utils.timezone import make_aware

min_dt = dt.datetime.combine(dt.date.today(), dt.time(7, 15))
max_dt = dt.datetime.combine(dt.date.today(), dt.time(15, 44))

# Changing format for Django
min_dt_aware = make_aware(min_dt)
max_dt_aware = make_aware(max_dt)

# Fetching all the data between 7:15:00 to 15:44:00 for current day
l1 = Visionsystem.objects.filter(start_datetime__range=(min_dt_aware, max_dt_aware))

print (l1) выход пустой список и проверка str (l1.query) дает:

'SELECT `visionsystem`.`id`, `visionsystem`.`Start_Datetime` ... FROM `visionsystem` WHERE 
`visionsystem`.`Start_Datetime` BETWEEN 2019-10-16 01:45:00 AND 2019-10-16 10:14:00'

Желаемый запрос будет:

'SELECT `visionsystem`.`id`, `visionsystem`.`Start_Datetime` ... FROM `visionsystem` WHERE 
`visionsystem`.`Start_Datetime` BETWEEN 2019-10-16 07:15:00 AND 2019-10-16 15:44:00'

Я не понимаю, почему Django-ORM запрашивает другое время , что указано?

Мои настройки часового пояса (в settings.py ):

TIME_ZONE = 'Asia/Kolkata'
USE_I18N = True
USE_L10N = True
USE_TZ = True

Как решить эту проблему, чтобы получить необходимые данные с 7: 15: 00 до 15: 44: 00 , для текущего дня ? ПРИМЕЧАНИЕ: я использую MySQL Database !!

models.py file :

    from django.db import models

    class Visionsystem(models.Model):

        start_datetime = models.DateTimeField(db_column='Start_Datetime', blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'visionsystem'

Ответы [ 2 ]

2 голосов
/ 16 октября 2019

MySql не поддерживает часовые пояса, он хранит дату и время в UTC, в то время как часовой пояс вашего приложения django равен Asia/Kolkata (UTC +5: 30).

Здесь django автоматически конвертирует часовой пояс вашего приложения в UTC перед запросом к базе данных MySQL. Это имеет смысл, поскольку, когда вы сохраняете данные с помощью приложения django, оно преобразует дату и время в время UTC, поэтому время 07:15:00 Kolkata будет сохранено как 01:45:00 в формате UTC.

Решение:

Вы можете сохранить данные MySql в часовом поясе UTC. Если существующие данные находятся в Kolkata часовом поясе, запустите запрос на обновление, вычтя -5:30 и сохранив всеновые данные в часовом поясе UTC.

ИЛИ

Если вашему приложению не требуется поддержка нескольких часовых поясов, вы можете изменить часовой пояс приложения на UTC. Это быстрое решение, но не очень хорошая идея, поскольку информация о часовом поясе усекается.

1 голос
/ 16 октября 2019

Короче говоря

  1. Django сохраняет магазин UTC в базе данных.
  2. Если вы не упомянете часовой пояс, будет использован часовой пояс, который вы упомянули в settings.py (в вашем случае, Asia/Kolkata, поэтому функция make_aware предполагает, что вы вводите дату и время с часовым поясом Asia/Kolkata. Но, как упоминалось в шаге 1., оно сохраняется как UTC. Оба времени указывают на одно и то же время, то есть время, описываемоеUTC и Asia / Kolkata одинаковы).
  3. В дополнение к 1 и 2, django преобразует ваш timezone_aware datetime (т.е. min_dt_aware и max_dt_aware) в UTC, чтобы сделать ваш запрос корректным во время выполнения запроса.

Вот подробное объяснение.

Обзор часовых поясов

Когда включена поддержка часовых поясов, Django сохраняет информацию о дате и временив UTC в базе данных, использует объекты даты-времени с учетом часовых поясов и переводит их в часовой пояс конечного пользователя в шаблонах и формах.

Значение отображается как UTC, которое печатается вSQL-запрос:

import pytz
utc = pytz.UTC
# Print the utc value of min_dt_aware and max_dt_aware
print(min_dt_aware.astimezone(utc), max_dt_aware.astimezone(utc))
# So, as you can see, these utc values are which you see in SQL queries.
...