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:从结构向量中,获取一个向量,该向量收集每个结构的一个字段