Django 1.9 中的 query.group_by

Posted

技术标签:

【中文标题】Django 1.9 中的 query.group_by【英文标题】:query.group_by in Django 1.9 【发布时间】:2016-06-04 03:27:00 【问题描述】:

我正在将代码从 Django 1.6 移动到 1.9。 在 1.6 中我有这个代码

models.py

class MyReport(models.Model):
    group_id    =   models.PositiveIntegerField(blank=False, null=False)

views.py

query = MyReport.objects.filter(owner=request.user).query
query.group_by = ['group_id']
entries = QuerySet(query=query, model=MyReport)

查询将为每个 'group_id' 返回 一个 对象;由于我使用它的方式,任何带有 group_id 的表行都可以作为代表。

在 1.9 中,此代码已损坏。上面第二行之后的查询是:

SELECT "reports_myreport"."group_id", ... etc FROM "reports_myreport" WHERE "reports_myreport"."owner_id" = 1 GROUP BY "reports_myreport"."group_id", "reports_report"."otherfield", ...

基本上它列出了group by子句中的所有表字段,使查询返回整个表。

尽管我在调试器中看到

query.group_by = ['group_by'] 

看起来 query.group_by 不是 1.9 中的方法,1.7-1.9 的更改日志也没有表明发生了某些变化。

有没有更好的方法——不依赖于内部 Django 的东西——我可以用于我的查询?

有什么方法可以修复我当前的查询吗?

【问题讨论】:

group_id 与您的MyReport 有什么关系?您能否向您的模型展示相关部分? @Sayse `group_id' 是模式中的一个简单字段。我用相关行编辑了问题 啊,好吧,我原以为它是一个外键……你在找MyReport.objects.filter(owner=request.user).distinct('group_id')吗? @Sayse 目前我没有使用 Postgres,所以我不确定 100%。 distinct(field) 返回表行还是仅返回不同的字段?我总是可以做类似的事情,但这似乎不是正确的解决方案:`objs = MyReport.objects.filter(owner=request.user).values_list('group_id', flat=True).distinct() for o in对象:MyReport.objects.filter(owner=request.user, group_id=o)[0] ` 它返回不同的对象是的。所以完整的模型 【参考方案1】:

您可以使用order_by() 来获取排序的结果,在同一个查询中,您可以按第二个条件排序。

如果您想获取组,则需要遍历集合以检索这些值。

如果你消费了查询返回的所有结果,你可以考虑:

a) itertools.groupby 改为在内存中分组,但您不应该将它用于大型数据集。

b) 另一种选择是使用Manager.raw(),但您需要在 Django 中编写 SQL,如下所示:

for report in MyReport.objects.raw('SELECT * FROM reporting_report GROUP by group_id'):
     print(report)

这适用于大型数据集,但您可能会失去与某些数据库引擎的兼容性。

奖励:我建议您在重写之前了解旧代码的确切作用。

【讨论】:

旧代码会为每个 group_id 返回一个条目(完整的表格行)。我不知道它是否错误地工作并且现在按设计工作。您的两种解决方案都应该有效,但是正如您自己提到的那样,它们都会遇到问题。我在上面的评论中的解决方案(无法让code 工作)也有效,但我查询的组数远非理想...... 显然,旧代码错误地工作了。在没有聚合的情况下进行 group_by 并没有真正定义。上面的建议(以及我在之前的评论中的建议)有效。在 Postgres 中,这可以更简单地完成。

以上是关于Django 1.9 中的 query.group_by的主要内容,如果未能解决你的问题,请参考以下文章

django 1.9 中的 from django.views.generic.simple import direct_to_template 相当于啥

如何在 django 1.9 中删除 django-admin 中的保存并继续编辑按钮,使其不存在?

DJango 1.9 个人资料注册+更新

刷新单应用程序 django 1.9

Django 1.9 在迁移中删除外键

如何在 Django 1.9 中删除 DB (sqlite3) 以从头开始?