2010-05-23 245 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') 

(显然是错误的,但我都快不懂得重新创建结构给你确切的正确的说法,小提琴并且阅读文档)

尽管在同一份文档中使用连接语法,但您可以在其中一次使用所有资产。