Django按年,月,日,小时和分钟过滤日期时间

时间:2014-02-13 13:56:18

标签: mysql django datetime timezone django-1.6

我是aware of problems,在Django中过滤了日期时间。这就是我构建原始查询集的原因:

query = 'SELECT * FROM meteorological_data_base.meteorological_data'

if year is not None:
    query += ' WHERE EXTRACT(YEAR FROM date_time) = ' + year
    if month is not None:
        query += ' AND EXTRACT(MONTH FROM date_time) = ' + month
        if day is not None:
            query += ' AND EXTRACT(DAY FROM date_time) = ' + day
            if hour is not None:
                query += ' AND EXTRACT(HOUR FROM date_time) = ' + hour
meteorological_data_list = MeteorologicalData.objects.raw(query)

我知道SQL注入,这只是为了测试而编写的。问题是因为Pagination我需要查询集。现在我尝试了this solution,只有在我只指定年份部分时它才有效:

MeteorologicalData.objects.filter(date_time__year=2010)

如果我也传入月份,则返回空的查询集:

MeteorologicalData.objects.filter(date_time__year=2010, date_time__month=1)

当我使用Django调试工具栏时,我可以看到Django生成什么样的SQL查询。对于最后一个例子(年和月),它产生了这个:

SELECT COUNT(*) FROM `meteorological_data` WHERE (EXTRACT(MONTH FROM CONVERT_TZ(`meteorological_data`.`date_time`, 'UTC', 'Europe/Ljubljana')) = 1 AND `meteorological_data`.`date_time` BETWEEN '2009-12-31 23:00:00' and '2010-12-31 22:59:59')

我在mysql控制台中试过这个,肯定会返回0行。如果我删除了CONVERT_TZ命令:

SELECT COUNT(*) FROM `meteorological_data` WHERE (EXTRACT(MONTH FROM `meteorological_data`.`date_time`) = 1 AND `meteorological_data`.`date_time` BETWEEN '2009-12-31 23:00:00' and '2010-12-31 22:59:59')

它可以正常工作。现在我正在使用时区感知日期时间。我在设置中的配置:

TIME_ZONE = 'Europe/Ljubljana'
USE_TZ = True

所以最后的问题是。如何使用不会转换为时区感知日期时间的过滤器命令。数据已经以UTC格式存储。

编辑: 好的,我发现原因是missing TIMEZONE table in MySql。但是,如何在不转换为TIMEZONE的情况下进行过滤?

1 个答案:

答案 0 :(得分:0)

如果您关闭USE_TZ设置会怎样?此外,(假设您清理SQL以使用参数化查询),您可以使用.raw()方法返回RawQuerySet

编辑:经过审核,如果问题是您查询的数据是UTC但是您使用的日期时间不是,为什么不在运行查询之前将日期时间转换为UTC?