2009-11-03 216 views
4

我需要編寫一個查詢,返回所有對象少於或等於某個月的特定日期。這一年並不重要。這是很容易通過特定的一天/每月能拿到一個對象(假設now = datetime.datetime.now()):Django日期篩選日期月

posts = TodaysObject.objects.filter(publish_date__day=now.day, publish_date__month=now.month) 

但我不能這樣做:

posts = TodaysObject.objects.filter(publish_date__day__lte=now.day, publish_date__month=now.month) 

看來,Django的認爲我正在試圖做的組合多個字段查找時的連接(publish_date__day__lte)。在Django中做這件事的最好方法是什麼?

回答

7

試試這個:

選項1:

from django.db.models import Q 

datafilter = Q() 
for i in xrange(1, now.day+1): 
    datafilter = datafilter | Q(publish_date__day=i) 
datafilter = datafilter & Q(publish_date__month=now.month) 
posts = TodaysObject.objects.filter(datafilter) 

選項2:

執行原始SQL查詢:

def query_dicts(query_string, *query_args): 
    from django.db import connection 
    cursor = connection.cursor() 
    cursor.execute(query_string, query_args) 
    col_names = [desc[0] for desc in cursor.description] 
    while True: 
     row = cursor.fetchone() 
     if row is None: 
      break 
     row_dict = dict(izip(col_names, row)) 
     yield row_dict 
    return 
posts = query_dicts('SELECT * FROM tablename WHERE DAY(publish_date)<=%s AND MONTH(publish_date)=%s', now.day, now.month) 

使用額外的()函數:

posts = TodaysObject.objects.extra([where='DAY(publish_date)<=%d AND MONTH(publish_date)=%d' % (now.day, now.month)]) 

假設您正在使用MySQL。對於PostgreSQL,您需要將DAY(publish_date)和MONTH(publish_date)分別更改爲DATE_PART('DAY',publish_date)和DATE_PART('MONTH',publish_date)。

+0

選項1是要走的路。不用擔心將來轉移到另一個數據庫引擎。 – 2009-11-03 01:42:38

+0

非常感謝你的幫助和深入的答案,選項1工作得很好。 – Mark 2009-11-03 03:45:36

1

它不總是可以從一個數據庫引擎移植到另一個數據庫引擎,但是您可能需要查看extra() queryset方法。

from django docs

這可以讓你注入原始SQL構造比Django的查詢集API更復雜的查詢。

如果您的應用程序需要可移植到不同的數據庫引擎,則可以嘗試重新構建,以便擁有日,月和年整數字段。