【问题标题】:Why isn't there a simple group_by in Django?为什么 Django 中没有简单的 group_by?
【发布时间】:2016-10-04 12:36:45
【问题描述】:

我有一个模型:

class Person(models.MyModel):
    department = models.ForeignKey('Department')
    start_date = models.DateField()

class Department(models.SomeModel):
    name = models.CharField()

我希望在我的模板中能够创建一个简单的表格,我可以在其中按两个属性对人员进行分组:department__namestart_date

这样,同一日期开始的部门名称相同的人员将显示在同一行中。

我知道有一个模板标签叫regroup,但是我只能给出三个参数,其中一个可以是grouper

好吧,我想我可以在我的view.py 中使用类似这样的方式进行此查询:

Person.objects.all().group_by('start_date','department__name')

但我错了。没有这种方法。

有什么方法可以简单地实现这一点?

编辑 1

相同的属性是指类的对象。例如:

假设这是数据库:

姓名 |部门 |开始日期

鲍勃|销售 | 2012 年 12 月 12 日

萨拉|销售 | 2012 年 12 月 12 日

约翰 |金融 | 13-11-2012

那么下面的函数会是这样的:

功能:

Person.objects.all().group_by('department__name', 'start_date')

输出:

销售 | 2012 年 12 月 12 日 |鲍勃,萨拉

财务 | 13-11-2012 |约翰

这样,Sara 和 John 已按部门AND开始日期分组。

【问题讨论】:

  • “按两个属性对人进行分组”是什么意思?你能举一个期望输出的例子吗?
  • 是的。我已经编辑了我的问题。我希望现在更好。

标签: python django


【解决方案1】:

这不是 SQL group by 的含义——在 SQL 中,您必须选择为 Sales - 12/12 行返回 Bob 或 Sara 中的哪一个,您不能同时拥有这两者。我会在 Python 中进行此处理,您想要的没有真正的 SQL。

例如,保留(部门名称,日期)元组的字典和名称列表作为值:

from collections import defaultdict

table = defaultdict(list)

for department, date, name in Person.objects.values_list(
        'department__name', 'start_date', 'name'):
    table[(department, date)].append(name)

【讨论】:

  • 就可以了。谢谢!
【解决方案2】:

您可以在 django 中执行 group_by 的方式是使用 valuesaggregate

例如,你可以这样来达到你想要的结果:

Person.objects.all().values('department__name', 'start_date').annotate(Count('start_date'))

但是我相信你不能在一个字符串中得到所有的名字,而且 AFAIK 你也不能在 mysql 上用简单的GROUP BY 来做到这一点。

编辑:刚才我了解到您想要对两个值进行分组,因此您可以执行以下操作:

    Person.objects.all().values('department__name', 'start_date')\
        .annotate(Count('start_date'))\
        .annotate(Count('department__name'))\
        .values_list('department__name','start_date')

【讨论】:

  • 我不需要计算我有多少start_dates。我只需要将相似的分组在同一行中。您提出的输出将类似于:{'start_date__count': 20}
  • 可以在注解后面加上 values_list。我已将其添加到我的编辑中:)
猜你喜欢
  • 2014-08-20
  • 2011-08-30
  • 2016-11-28
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
相关资源
最近更新 更多