2010-05-23 160 views
2

我一直在這裏潛伏和學習一段時間。現在我有一個問題,我無法看到一個簡單的解決方案。爲了學習Django我正在建立一個基本上跟蹤預訂項目的應用程序。 我想要做的是顯示一個項目已被預訂的選定年份每月有多少天。Django聚合日期範圍

我有以下型號:

Asset(Model) 

BookedAsset(Model): 
asset = models.ForeignKey(Asset) 
startdate = models.DateField() 
enddate = models.DateField() 

所以具有以下條目:

asset 1, 2010-02-11, 2010-02-13 
asset 2, 2010-03-12, 2010-03-14 
asset 1, 2010-04-30, 2010-05-01 

我想獲得返回以下:

asset 1 asset 2 
------- ------- 
Jan = 0 Jan = 0 
Feb = 2 Feb = 0 
Mar = 0 Mar = 2 
Apr = 1 Apr = 0 
May = 1 May = 0 
Jun = 0 Jun = 0 
Jul = 0 Jul = 0 
Aug = 0 Aug = 0 
Sep = 0 Sep = 0 
Oct = 0 Oct = 0 
Nov = 0 Nov = 0 
Dec = 0 Dec = 0 

我知道我需要首先得到某個日期範圍內的天數(如果它們超出當前月份並進入日期範圍,則保持跟蹤e下個月),然後對天數進行聚合。我只是堅持如何在Django中優雅地做到這一點。

任何幫助(或提示正確的方向)非常感謝。

回答

0

在我自定義查詢去作爲解決我的問題到底:

cursor = connection.cursor() 
cursor.execute("""select to_char(allmonths.yeardate::date, 'YYYY/MM/DD') as monthdate, 
        COUNT("day") as bookings 
        from (
        select distinct date_trunc('month', (date %s - offs)) as yeardate 
        from generate_series(0,365,28) as offs 
        ) as allmonths 
        left join bookings_bookedassetday 
        on EXTRACT(MONTH from "day")=EXTRACT(MONTH from yeardate) 
        and asset_id=%s and EXTRACT(YEAR from "day") = %s 
        group by allmonths.yeardate 
        order by allmonths.yeardate asc""", [year+'-12-31', id, year]) 

query = cursor.fetchall() 

也許這不是最django-ist這樣做的方式,但我發現它比純django更容易找出方法:

如果別人有更好的選擇,我所有的耳朵:)

+0

你應該接受這個答案,所以社區可以一眼就知道你不需要更多的幫助。 – 2010-08-09 00:20:10

0

我想不出用你擁有的模型結構來做這件事的方法。

這是一個相當複雜的要求,但是您解決它可能需要相當多的自定義SQL。我認爲首先,儘管您可能需要考慮更改結構,以便您有一張BookedAssetDay表格,該表格分別代表每個預訂日期。

class BookedAsset(models.Model): 
    asset = models.ForeignKey(Asset) 
    day = models.DateField() 

然後查詢看起來是這樣的:

BookedAsset.objects.extra(
    select={'month': 'MONTH(day)'} 
).values('asset', 'month').annotate(Count('bookedasset__month')) 
+0

最後我想我將通過添加額外的表格來解決您的問題。唯一的問題是,多個用戶擁有多個資產,因此BookedAssetDay表可能會變大... – klaut 2010-05-23 20:45:04

+0

或者我也可以使用此解決方案來解決此問題:http://stackoverflow.com/questions/1371280/query-for -values-based-date-w-django-orm 無論如何,我非常感謝你的回覆,丹尼爾! :) – klaut 2010-05-23 20:49:33

0

我不會去任何回答以上(甚至我喜歡衝出一些自定義的SQL,但我沒有這樣做,至少在5年),並且您的模型足夠簡單,可以在關係範式中使用。

你要找的是答案在Django的聚合功能的註釋()函數: http://docs.djangoproject.com/en/dev/topics/db/aggregation/ 你需要知道的唯一的事情是如何在一個月的日期,這是查詢集文檔中解釋得: http://docs.djangoproject.com/en/dev/ref/models/querysets/#month

一個粗略的例子得到它爲一項資產:

BookedAsset.objects.filter(asset=asset).annotate(month_count=Count('startdate__month')).order_by('startdate__month') 

(顯然是錯誤的,但我都快不懂得重新創建結構給你確切的正確的說法,小提琴並且閱讀文檔)

儘管在同一份文檔中使用連接語法,但您可以在其中一次使用所有資產。