我是aware of problems在Django中過濾日期時間。這就是爲什麼我建立一個原始查詢集: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
所以最終的問題是。如何使用不會轉換爲可識別時區的日期時間的filter命令。數據已經以UTC格式存儲。編號: 好的,我發現原因是missing TIMEZONE table in MySql。但是,仍然如何過濾而不轉換爲TIMEZONE?
如果我關閉USE_TZ設置,它按預期工作。但在其他一些頁面中,我確實需要知道時區的日期時間。我希望有某種設置可以說我只想爲代碼塊的特定腳本禁用它。 –
剛試過RawQuerySet。問題是它沒有方法len或count!來自分頁文檔:'請注意,您可以使用count()或__len __()方法爲Paginator提供列表/元組,Django QuerySet或任何其他對象。當確定傳遞對象中包含的對象的數量時,如果傳遞的對象沒有count()方法,Paginator將首先嚐試調用count(),然後回退到使用len()。這允許諸如Django的QuerySet之類的對象在可用時使用更高效的count()方法。 –
您可以將RawQuerySet的結果包裝在list()中,但是請注意將[將整個結果集加載到內存中。] (http://stackoverflow.com/questions/2317452/django-count-rawqueryset) – Tom