简体   繁体   English

如何将相关对象的最大值注释到Django查询集

[英]How to annotate the Max of a related object to a Django queryset

I have a Django website where users can make groups, and then write replies under the said groups. 我有一个Django网站,用户可以在其中进行分组,然后在所述分组下进行答复。

Simply put: 简单的说:

class Group(models.Model):
    owner = models.ForeignKey(User)        
    #some attributes

class Reply(models.Model):
    text = models.TextField(validators=[MaxLengthValidator(500)])
    writer = models.ForeignKey(User)

For a given user, I want to find all groups that she either made, or ever replied under (even if once). 对于给定的用户,我想查找她创建的或曾经回复过的所有组(即使有一次)。 Furthermore, from all such groups, I want to extract the ID of the most recent reply - whether made by the user herself, or by someone else. 此外,我想从所有此类组中提取最近答复的ID,无论是用户本人还是其他人。

To accomplish the above, I have tried: 为了达到上述目的,我尝试了:

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)

This doesn't work - in ids , I only get the most recent reply written by self.request.user herself, not the absolute most recent reply (written by anyone) under each group. 这不起作用-在ids ,我只能得到self.request.user自己写的最新回复,而不是每个组下的绝对最新回复(任何人写的)。 I find that weird because seemingly, this ought to work, no? 我觉得这很奇怪,因为看起来应该可行,不是吗? Maybe I'm referencing the reverse foreignkey incorrectly. 也许我错误地引用了反向外键。

Can you help me fix this, or suggest an alternative? 您能帮我解决这个问题,还是建议其他方法?

The following is how I'm currently accomplishing it. 以下是我目前正在完成的工作。 I assign the ids of all relevant groups to groups . 我将所有相关组的ID分配给groups I find the ids of max replies under each and assign them to replies . 我在每个标题下找到最大答复的ID,并将其分配给replies Finally, I construct a queryset around 60 such replies, assigning that to replies_qs . 最后,我围绕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]

This is 3 DB accesses, would prefer to do it in less, if someone has a suggestion. 这是3个DB访问,如果有人提出建议,则希望减少访问次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM