2014-02-13 222 views
1

我是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?

回答

0

如果您關閉了USE_TZ設置,會發生什麼情況?此外,(假設您清理SQL以使用參數化查詢),您可以使用.raw()方法取回RawQuerySet

編輯:如果問題是您正在查詢的數據是UTC,但是您使用的日期時間不是,那麼爲什麼不在運行查詢之前將日期時間轉換爲UTC?

+0

如果我關閉USE_TZ設置,它按預期工作。但在其他一些頁面中,我確實需要知道時區的日期時間。我希望有某種設置可以說我只想爲代碼塊的特定腳本禁用它。 –

+0

剛試過RawQuerySet。問題是它沒有方法len或count!來自分頁文檔:'請注意,您可以使用count()或__len __()方法爲Paginator提供列表/元組,Django QuerySet或任何其他對象。當確定傳遞對象中包含的對象的數量時,如果傳遞的對象沒有count()方法,Paginator將首先嚐試調用count(),然後回退到使用len()。這允許諸如Django的QuerySet之類的對象在可用時使用更高效的count()方法。 –

+0

您可以將RawQuerySet的結果包裝在list()中,但是請注意將[將整個結果集加載到內存中。] (http://stackoverflow.com/questions/2317452/django-count-rawqueryset) – Tom

相關問題