【问题标题】:Django: Group by?姜戈:分组?
【发布时间】:2011-01-27 01:46:37
【问题描述】:

我正在寻找类似以下的内容:

previous_invoices = Invoice.objects.filter(is_open=False)
                                   .order_by('-created')
                                   .group_by('user')

但是group_by() 不存在...

这将找到每个用户最近关闭的发票。

这个aggregation API 似乎可以让你为计数和总和做这样的事情,但我不需要计数或总和或任何东西,我实际上想要发票对象!

【问题讨论】:

  • 在使用 group by 时是否定义了 selected 事物?我希望它会根据 sql 实现产生不同的结果...
  • @user3012759 否。排序发生在分组之后,您在该组中返回的记录是未定义的。我花了一段时间才真正理解这一点。 ONLY_FULL_GROUP_BY 应该默认启用 IMO,这样你就不会犯这个错误。
  • 嘿@mpen 我添加了一个更新的尝试来回答。想看看吗?
  • @JohnMoutafis 我当然可以看。我不再使用 Django,但如果我这样做的话,那看起来会很有帮助:-)
  • 很高兴知道@mpen :)

标签: python django group-by django-orm


【解决方案1】:

选项 1:

虽然 Django 中不存在 group_by(),但您可以尝试使用 latest() 方法检索每个用户最近关闭的发票并过滤用户:

previous_invoices = Invoice.objects.filter(user=my_user, is_open=False)
                                   .latest('created') 

对于旧版本的 Django,latest() 不存在,查询将如下所示:

previous_invoices = Invoice.objects.filter(user=my_user, is_open=False)
                                   .order_by('-created')[0]

选项 2:

更新:从那时起,我在这里添加了一个问答样式示例:How to execute a GROUP BY ... COUNT or SUM in Django ORM?,它展示了如何在 Django ORM 上模拟 GROUP BY 操作。

如果您绝对想创建group_by 的效果,那么您可以手动创建一个,如此处接受的答案所示:Django GROUP BY field value

  1. 使用.values_list()flat=True 来获取数据库中现有值的列表(如果您事先不知道它们)。也可以使用.distinct() 来消除重复值,因为我们不关心这些:

    value_list = MyModel.objects.values_list(
        'interesting_field', flat=True
    ).distinct()
    
  2. 现在遍历value_list 并填写您的字典:

    group_by_value = {}
    for value in value_list:
        group_by_value[value] = MyModel.objects.filter(interesting_field=value)
    

现在group_by_value 字典包含不同值作为键 在您的interesting_field 中,作为查询集对象的值,每个 包含MyModelinteresting_field=a value from value_list 的条目。


注意:

存在这个库 django-group-by,它声称在 Django 上添加了一个 group_by(),您可能想检查一下。

【讨论】:

    【解决方案2】:

    this page from 2007 将其入侵到 django,但这没有实际意义,因为 1.1 之前的版本确实有一个未记录的 group_by`。但this thread from a year ago 似乎有一些见解。本质上:

    Django 故意不公开“GROUP BY”或类似的东西,在 ORM。虽然事实上我们是 通过关系存储后端 有时会通过 ORM API 泄​​漏 是相当 SQL 不可知的。相反,我们 暴露特定的片段 碰巧的功能 使用“GROUP BY”实现 变成了 SQL(很可能是 由一些完全不同的实施 一组神奇的仙女 不同的存储系统后端)。

    另请参阅使用 extra 的提及,以及 that 可能失败的神奇方式。祝你好运。

    【讨论】:

      猜你喜欢
      • 2020-08-17
      • 2013-02-22
      • 2016-01-06
      • 2014-06-02
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      相关资源
      最近更新 更多