Django分组查询

时间:2010-05-14 01:03:21

标签: python django

我有以下(简化)模型:

class Donation(models.Model):
    entry_date = models.DateTimeField()

class Category(models.Model):
    name = models.CharField()

class Item(models.Model):
    donation = models.ForeignKey(Donation)
    category = models.ForeignKey(Category)

我正在尝试显示按捐赠年份分组的每个类别的项目总数。

我试过这个:

Donation.objects.extra(select={'year': "django_date_trunc('year', 
    %s.entry_date)" % Donation._meta.db_table}).values('year', 
    'item__category__name').annotate(items=Sum('item__quantity'))

但我在item__category__name上收到了字段错误。

我也试过了:

Item.objects.extra(select={"year": "django_date_trunc('year', 
    entry_date)"}, tables=["donations_donation"]).values("year", 
    "category__name").annotate(items=Sum("quantity")).order_by()

这通常会得到我想要的东西,但物品数量计数乘以捐赠记录的数量。

有什么想法吗?基本上我想显示这个:

2010
  - Category 1: 10 items
  - Category 2: 17 items

2009
  - Category 1: 5 items
  - Category 3: 8 items

2 个答案:

答案 0 :(得分:0)

这篇文章看起来就像你要找的那样:

Django equivalent for count and group by

根据您的Django版本,您可能会也可能无法使用它。

答案 1 :(得分:0)

我意识到你可能已经编写了原始SQL,但当我看到你想要显示数据的方式时,我想到了以下内容:

如果可以在模板级别执行此操作,您可能可以战略性地使用regroup标记和长度过滤器。

重新组合采用“相似对象列表”,因此查询集可能正常工作,但文档显示字典列表,所以我在这里使用了值:

item_listing = Item.objects.values('category__name', 'donation__entry_date')
# use your favourite method to extract the year information into a key in item_listing
item_listing = ...

现在在模板中,例如:

<ul>
{% for year_group in item_listing %}
    <li>{{ year_group.grouper }}
    <ul>
        {% regroup year_group.list by category__name as category_listing %}
        {% for category_group in category_listing %}
        <li>
        Category: {{ category_group.grouper }}
        Count: {{ category_group.list|length }}
        </li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

我不确定regroup标签是否像那样嵌套(没试过)。另外,如果你有大量的数据,我不知道重组的表现有多好,但是再一次,总是有缓存......

如果您决定使用此功能,请务必记下重新分组文档中提到的订购问题。