Django聚合日期范围

时间:2010-05-23 13:55:17

标签: python django date django-aggregation

我一直在潜伏和学习这里一段时间。现在我有一个问题,不知怎的,我看不到一个简单的解决方案。为了学习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

我知道我需要首先获得日期范围内的天数(并记录它们是否超出当前月份和下个月),然后对天数进行重新调整。我只是坚持如何在Django中优雅地做到这一点。

非常感谢任何帮助(或正确方向的暗示)。

4 个答案:

答案 0 :(得分: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'))

答案 1 :(得分: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更容易解决:|

如果其他人有更好的选择,我全都耳朵:)

答案 2 :(得分:0)

答案 3 :(得分:0)

还有另一种解决方案是通过数据库视图进行操作,并使用元类选项managed = False将该视图映射到django模型

此处有详细说明:http://anthony-tresontani.github.com/Django/2012/09/12/wka-django-orm-limitations/