Django-queryset 每个字段获取一个对象=foo

Posted

技术标签:

【中文标题】Django-queryset 每个字段获取一个对象=foo【英文标题】:Django-queryset get one object per field=foo 【发布时间】:2010-11-21 22:36:52 【问题描述】:

我对用户有一个基本的 FK,称之为所有者

class Baz(models.Model):

    owner = models.ForeignKeyField(User)


    ....
    ....

现在,有了一个 Baz 的查询集,我可以链接一些东西,每个所有者只给我一个 Baz?

【问题讨论】:

因此,给定一个 Baz 的 QuerySet,您希望对其进行过滤,以使 QuerySet 返回的任何两个对象都不具有与所有者相同的用户对象。这就是你想要的吗? 听起来你有这个想法 【参考方案1】:

编辑:这有更高的工作机会:

CheckIn.objects.extra(where=['checkins_checkin.id = (SELECT MAX(checkins_checkin.id) FROM checkins_checkin temp, auth_user WHERE auth_user.id = temp.id AND temp.user_id = checkins_checkin.user_id)',]).count() 

【讨论】:

CheckIn.objects.extra(where=['checkins_checkin.id = (SELECT checkins_checkin.id FROM checkins_checkin temp, auth_user WHERE auth_user.id = temp.id ORDER BY id DESC LIMIT 1)',] ).count() Out[4]: 18 In [5]: CheckIn.objects.all().count() Out[5]: 18 这个测试数据集中只有 2 个所有者,但我通过该查询返回了所有 18 个对象。 你说得对,我忘了在 where 子句中添加用户条件。我相应地更新了我的答案。【参考方案2】:

这可能不是最好的解决方案(希望将其保留在内存之外和查询集中)但是:

>>> d=
>>> [d.setdefault(str(a.owner),a) for a in qs ]
>>> d.values()

确实返回一个对象列表,每个所有者都是最新的。我对这个解决方案的可扩展性有真正的保留。

【讨论】:

我建议使用此解决方案,然后在出现问题时对其进行优化,也许记下以稍后再修复。 谢谢,尽管我讨厌它,但我也在使用它。如果你确实改进了这段代码,你能发布你的改进吗?【参考方案3】:

我相信问题是如何运行这个等价物:

SELECT * FROM myapp_baz GROUP BY owner_id;

将为每个唯一的 owner_id 返回一行。

看起来这样可以解决问题:

qs = Baz.objects.all()
qs.query.group_by = ['owner_id']

# Seems to do the trick
print [item for item in qs]

【讨论】:

似乎很接近,我会进一步研究。列“app_baz.X”必须出现在 GROUP BY 子句中或在聚合函数中使用 你能提供一个代码sn-p吗?在我的示例中,“owner_id”是数据库中的一个列(如果您的 Baz 对象具有“owner = ForeignKey(SomeObject)”,那么您也应该有一个 owner_id 列)。 owner_id 是一列,我得到 ProgrammingError: column "checkins_checkin.id" must出现在 GROUP BY 子句中或在聚合函数中使用 checkins_checkin.id 是主键.. 但是,如果我将它添加到 group_by 列表中,然后它继续对 nex 字段产生相同的错误。 我们正在使用的模型是 Checkin,还是另一个 fk?另外,fwiw,我在这里使用 Django 1.1。 这确实适用于简单的情况;此页面上的其他项目与发生订购的情况密切相关......【参考方案4】:

您真正需要的功能是 GROUP BY。但是,Django 通常不支持构建不直接输出模型实例的查询集。在这种情况下,您有两种方法:

Baz.objects.values('owner').distinct()

这将使您获得每个不同的所有者,而不是 Baz 对象本身。

Baz.objects.filter(pk__in=Baz.objects.values('owner').distinct())

上面将执行一个子查询(至少在 mysql 中)并且应该给出预期的结果,但这不是检索它的最有效方法。

最后,由于已经添加了聚合,您可以编写一个自定义聚合类,它可以作为一种“Distinct”和简单的“GROUP BY”工作。

【讨论】:

啊,子查询不太正确,请使用下面的组,如下所示。

以上是关于Django-queryset 每个字段获取一个对象=foo的主要内容,如果未能解决你的问题,请参考以下文章

如何在获取值之前对JSONObject中的每个元素进行空检查?

SystemVerilog:从结构向量中,获取一个向量,该向量收集每个结构的一个字段

根据雪花中的字段值获取每个日期和数据透视表的最后一个值

获取每个组的最大字段的整个记录

重用自定义UITableViewCell,如何获取每个单元格文本字段的文本进行保存?

如何正确解析一组 Fetch 响应