如何将相关对象的最大值注释为 Django 查询集
How to annotate the Max of a related object to a Django queryset
我有一个 Django 网站,用户可以在其中进行分组,然后在所述分组下写回复。
简单地说:
class Group(models.Model):
owner = models.ForeignKey(User)
#some attributes
class Reply(models.Model):
text = models.TextField(validators=[MaxLengthValidator(500)])
writer = models.ForeignKey(User)
对于给定的用户,我想找到她创建的或曾经回复过的所有群组(即使有一次)。此外,从所有这些组中,我想提取最近回复的 ID——无论是由用户自己还是其他人做出的。
为了实现上述目标,我尝试过:
groups = Group.objects.filter(Q(owner=self.request.user)|Q(reply__writer=self.request.user)).distinct()
ids = groups.annotate(max_reply=Max('reply__id')).values_list('max_reply', flat=True)
这不起作用 - 在 ids
中,我只得到 self.request.user
她自己写的最新回复,而不是每个组下的绝对最新回复(任何人写的)。我觉得这很奇怪,因为看起来,这应该行得通,不是吗?也许我错误地引用了反向外键。
你能帮我解决这个问题,或者建议一个替代方案吗?
以下是我目前的实现方式。我将所有相关组的 ID 分配给 groups
。我在每个下面找到最大回复的 ID,并将它们分配给 replies
。最后,我构建了一个包含 60 个这样的回复的查询集,并将其分配给 replies_qs
。
groups = Group.objects.filter(Q(owner=self.request.user)|Q(reply__writer=self.request.user)).distinct().values_list('id', flat=True)
replies = Reply.objects.filter(which_group__in=groups).values('which_group_id').annotate(Max('id')).values_list('id__max', flat=True)
replies_qs = Reply.objects.filter(id__in=replies)[:60]
这是 3 次 DB 访问,如果有人有建议,我希望在更少的时间内完成。
我有一个 Django 网站,用户可以在其中进行分组,然后在所述分组下写回复。
简单地说:
class Group(models.Model):
owner = models.ForeignKey(User)
#some attributes
class Reply(models.Model):
text = models.TextField(validators=[MaxLengthValidator(500)])
writer = models.ForeignKey(User)
对于给定的用户,我想找到她创建的或曾经回复过的所有群组(即使有一次)。此外,从所有这些组中,我想提取最近回复的 ID——无论是由用户自己还是其他人做出的。
为了实现上述目标,我尝试过:
groups = Group.objects.filter(Q(owner=self.request.user)|Q(reply__writer=self.request.user)).distinct()
ids = groups.annotate(max_reply=Max('reply__id')).values_list('max_reply', flat=True)
这不起作用 - 在 ids
中,我只得到 self.request.user
她自己写的最新回复,而不是每个组下的绝对最新回复(任何人写的)。我觉得这很奇怪,因为看起来,这应该行得通,不是吗?也许我错误地引用了反向外键。
你能帮我解决这个问题,或者建议一个替代方案吗?
以下是我目前的实现方式。我将所有相关组的 ID 分配给 groups
。我在每个下面找到最大回复的 ID,并将它们分配给 replies
。最后,我构建了一个包含 60 个这样的回复的查询集,并将其分配给 replies_qs
。
groups = Group.objects.filter(Q(owner=self.request.user)|Q(reply__writer=self.request.user)).distinct().values_list('id', flat=True)
replies = Reply.objects.filter(which_group__in=groups).values('which_group_id').annotate(Max('id')).values_list('id__max', flat=True)
replies_qs = Reply.objects.filter(id__in=replies)[:60]
这是 3 次 DB 访问,如果有人有建议,我希望在更少的时间内完成。